zoukankan      html  css  js  c++  java
  • 静态代理、动态代理和CGLIB,SpringAOP中的代理

    静态代理、动态代理和CGLIB

      动态代理和CGLIB都是运行时构建代理对象,动态代理通过反射的方式,CGLIB通过java字节码织入继承父类的方式实现

    静态代理

      静态代理的核心在于,代理类和被代理的类实现同一个接口

    public interface IUserService {
        void save();
    }
    
    /**
     * 这是被代理的类
     */
    class UserServiceImpl implements IUserService {
        @Override
        public void save() {
            System.out.println("执行逻辑");
        }
    }
    
    /**
     * 1.和被代理的类实现同一个接口
     * 2.将被代理的类作为成员变量依赖进来
     * 3.代理类执行代理逻辑,执行被代理的类的逻辑
     */
    class UserServiceImplProxy implements IUserService {
    
        private IUserService userService;
    
        public UserServiceImplProxy(IUserService userService) {
            this.userService = userService;
        }
    
        @Override
        public void save() {
            System.out.println("执行前的代理逻辑");
            userService.save();
            System.out.println("执行后的代理逻辑");
        }
    }
    

    动态代理

      动态代理是JDK提供的一个代理接口,通过实现接口,然后构建代理类的方式来实现

    public interface IUserService {
        void save();
    }
    
    /**
     * 这是被代理的类,实现JDK提供的接口 InvocationHandler
     */
    class UserServiceImpl implements IUserService,InvocationHandler {
        @Override
        public void save() {
            System.out.println("执行逻辑");
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("执行前的代理逻辑");
            Object retVal = method.invoke(this, args);
            System.out.println("执行后的代理逻辑");
    
            return retVal;
        }
    }
    
    class Test {
        public static void main(String[] args) {
            //通过反射的方式构建代理对象
            IUserService proxyInstance = (IUserService)Proxy.newProxyInstance(UserServiceImpl.class.getClassLoader(),
                    UserServiceImpl.class.getInterfaces(),
                    new UserServiceImpl());
            System.out.println(proxyInstance);
            proxyInstance.save();
        }
    }
    

    CGLIB代理

      CGLIB是第三方库,通过继承的方式实现代理。好处就是不需要像JDK动态代理那样必须实现接口。通过对java字节码织入的方式实现代理。

    public interface IUserService {
        void save();
    }
    
    /**
     * 普通的实现类
     */
    class UserServiceImpl implements IUserService {
        @Override
        public void save() {
            System.out.println("执行逻辑");
        }
    }
    
    /**
     * 回调的类
     */
    class Callback implements MethodInterceptor {
        public Callback() {}
    
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println("执行前的代理逻辑");
            Object retVal = methodProxy.invokeSuper(obj, args);
            System.out.println("执行后的代理逻辑");
            return retVal;
        }
    }
    
    class Test  {
        public static void main(String[] args) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(UserServiceImpl.class);
            enhancer.setCallback(new Callback());
            IUserService userService = (IUserService) enhancer.create();
    
            userService.save();
        }
    }
    

    Spring对AOP的支持

    构建@Transactional的对象(CGLIB)

    AbstractAutowireCapableBeanFactory.doCreateBean()方法中,初始化操作;

    	// Initialize the bean instance.
    	Object exposedObject = bean;
    	try {
    		populateBean(beanName, mbd, instanceWrapper);
    		//初始化操作,就是在这里将已经反射生成好的对象再通过代理的模式构建代理对象
    		exposedObject = initializeBean(beanName, exposedObject, mbd);
    	}
    

    如下跟踪代码

    	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    		// ...省略代码
    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    		}
    
    		return wrappedBean;
    	}
    

    下面代码中Object current = processor.postProcessAfterInitialization(result, beanName);非常关键,当processor为AnnotationAareAspectJAutoProxyCreator时,会将对象使用对应的代理模式构建代理的对象

        @Override
    	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    			throws BeansException {
    
    		Object result = existingBean;
    		for (BeanPostProcessor processor : getBeanPostProcessors()) {
    		    //在这里进行代理对象的构建
    			Object current = processor.postProcessAfterInitialization(result, beanName);
    			if (current == null) {
    				return result;
    			}
    			result = current;
    		}
    		return result;
    	}
    

    构建代理对象的代码,getAdvicesAndAdvisorsForBean()方法获取切面的功能(比如事务管理器),在createProxy()方法构建代理对象

    	@Override
    	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    		//...
    			return wrapIfNecessary(bean, beanName, cacheKey);
    	    // ...
    	}
    	
    	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            // ...
        
        	// Create proxy if we have advice.
        	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        	if (specificInterceptors != DO_NOT_PROXY) {
        		this.advisedBeans.put(cacheKey, Boolean.TRUE);
        		Object proxy = createProxy(
        				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        		this.proxyTypes.put(cacheKey, proxy.getClass());
        		return proxy;
        	}
            // ...
    	}
    

    createProxy()中执行创建

    	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
    			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
    
    		// ...
            //创建工厂类
    		ProxyFactory proxyFactory = new ProxyFactory();
    		proxyFactory.copyFrom(this);
    
    		// ...
    
    		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    		proxyFactory.addAdvisors(advisors);
    		proxyFactory.setTargetSource(targetSource);
    		customizeProxyFactory(proxyFactory);
    
    		// ...
    		ClassLoader classLoader = getProxyClassLoader();
    		if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
    			classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
    		}
    		return proxyFactory.getProxy(classLoader);
    	}
    
    

    层层追踪proxyFactory.getProxy(classLoader)

    	public Object getProxy(@Nullable ClassLoader classLoader) {
    		return createAopProxy().getProxy(classLoader);
    	}
    
    	/**
    	 *
    	 */
    	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    		if (!NativeDetector.inNativeImage() &&
    				(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
    			Class<?> targetClass = config.getTargetClass();
    			if (targetClass == null) {
    				throw new AopConfigException("TargetSource cannot determine target class: " +
    						"Either an interface or a target is required for proxy creation.");
    			}
    			//判断是否是接口,或者是代理的类,那么就走动态代理
    			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
    				return new JdkDynamicAopProxy(config);
    			}
    			//否则走CGLIB动态代理
    			return new ObjenesisCglibAopProxy(config);
    		}
    		else {
    			return new JdkDynamicAopProxy(config);
    		}
    	}
    

    SpringAOP对AspectJ的支持

    构建AspectJ切面的对象

  • 相关阅读:
    关于自适应的矩形css布局
    关于在天机项目中遇到的常用git 命令
    关于es6中对象的扩展
    vue的钩子函数
    关于Javascript的forEach 和 map
    关于router-link的传参以及参数的传递
    关于vuex的项目中数据流动方式
    vue中关于prop
    提交Sublime Text 插件到Package Control
    写lua时需要注意的地方
  • 原文地址:https://www.cnblogs.com/lcmlyj/p/14661048.html
Copyright © 2011-2022 走看看