• AOP 底层实现原理


      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、测试

    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
  • 相关阅读:
    P1939 矩阵加速(数列)
    P3390 矩阵快速幂
    快速幂
    1236:区间合并
    1183:病人排队
    1230:寻找平面上的极大点
    1244:和为给定数
    1228 书架
    1222 放苹果
    洛谷5015标题统计
  • 原文地址:https://www.cnblogs.com/Latiny/p/10786452.html
Copyright © 2020-2023  润新知