AOP - 3 底层实现原理

  1、核心业务接口与实现

public interface IManager {

    void add(String item);
}
View Code
public class IManagerImpl implements IManager {

    private List<String> list = new ArrayList<>();

    @Override
    public void add(String item) {
        list.add(item);
    }
}
View Code

2、通知接口与实现

public interface Advice {

    void beforeAdvice();

    void afterAdvice();
}
View Code
public class AdviceImpl implements Advice {

    @Override
    public void beforeAdvice() {
        System.out.println("Method start time: " + System.currentTimeMillis());
    }

    @Override
    public void afterAdvice() {
        System.out.println("Method end time: " + System.currentTimeMillis());
    }
}
View Code

3、动态代理类(关联核心业务与通知切面)

public class ProxyFactory implements InvocationHandler {

    // 被代理对象
    private Object target;
    // 通知
    private Advice advice;

    /**
     * 通过目标对象返回动态代理对象
     * @return
     */
    public Object getProxy() {
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
        return proxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        advice.beforeAdvice();
        Object obj = method.invoke(target, args);
        advice.afterAdvice();
        return obj;
    }

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    public Advice getAdvice() {
        return advice;
    }

    public void setAdvice(Advice advice) {
        this.advice = advice;
    }
}
View Code

  4、通过配置文件反射实现代理、业务、通知

public class BeanFactory {

    Properties prop = new Properties();

    public BeanFactory(InputStream input) {
        try {
            prop.load(input);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取Proxy(代理对象) 的实例
     * @param name
     * @return
     */
    public Object getBean(String name) {
        // 获取ProxyFactory 的class 名称
        String className = prop.getProperty(name + ".proxy");
        Object proxy  = null;
        try {
            // 获取ProxyFactory 的class对象
            Class proxyClass = Class.forName(className);
            proxy = proxyClass.newInstance();

            // 根据配置文件实例化target 与 advice对象
            Object target = Class.forName(prop.getProperty(name + ".target")).newInstance();
            Object advice = Class.forName(prop.getProperty(name + ".advice")).newInstance();

            // 通过内省实现对ProxyFactory的属性赋值
            BeanInfo beanInfo = Introspector.getBeanInfo(proxyClass);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd : propertyDescriptors) {
                String propertyName = pd.getName();
                Method writeMethod = pd.getWriteMethod();
                if ("target".equals(propertyName)) {
                    writeMethod.invoke(proxy, target);
                } else if ("advice".equals(propertyName)) {
                    writeMethod.invoke(proxy, advice);
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return proxy;
    }
}
View Code

5、测试

扫描二维码关注公众号,回复: 7351454 查看本文章
public class AopTest {

    public static void main (String[] args) {
        // 读取配置文件
        InputStream input = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("cn/latiny/aopa/bean.properties");
        
        // 创建Bean的工厂类
        BeanFactory beanFactory = new BeanFactory(input);
        
        // 获取代理对象
        ProxyFactory proxyFactory = (ProxyFactory)beanFactory.getBean("bean");
        
        // 通过代理对象调用
        IManager bean = (IManager)proxyFactory.getProxy();
        bean.add("Latiny");
    }
}
View Code

猜你喜欢

转载自www.cnblogs.com/Latiny/p/10786452.html