• 3.AOP中的IntroductionAdvisor


    上篇中的自定义Advisor是实现的AbstractPointcutAdvisor,Advisor其实还有一个接口级别的IntroductionAdvisor

                       

    这个好像用的很少,网上搜了一些资料,说是基于Class的增强,接口的功能扩展,在原有的功能上增加一些其他接口定义的方法,可以将当前代理对象向上转型,然后调用接口中的方法

    这个功能暂时还不知道适用于什么场景

    示例:

    //定义一个some类,只有doSome方法
    @Component
    public class Some {
        public void doSome() {
            System.out.println("do some...");
        };
    }
    
    //定义一个other接口,提供doOther功能
    public interface IOther {
        public void doOther();
    }
    

      

    //定义一个通知器
    @Component
    public class OtherIntroductionAdvisor extends DefaultIntroductionAdvisor {
    
        public OtherIntroductionAdvisor() {
            super(new OtherIntroductionInterceptor());
        }
    
       // createBean的时候判断bean是否需要被代理
        @Override
        public boolean matches(Class<?> clazz) {
           //只代理some对象
            boolean assignableFrom = clazz.isAssignableFrom(Some.class);
            return assignableFrom;
        }
    }
    
    //定义一个通知,要实现IOther接口
    public class OtherIntroductionInterceptor implements IntroductionInterceptor, IntroductionInfo, IOther {
    
        //实现doOther方法
        @Override
        public void doOther() {
            System.out.println("do other ...");
        }
        
        //扩展功能的实现
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            //当前方法的声明类是否实现了需要拓展功能的接口
            if (implementsInterface(invocation.getMethod().getDeclaringClass())) {
                 //调用this的此方法
                return invocation.getMethod().invoke(this, invocation.getArguments());
            }
            return invocation.proceed();
        }
    
        @Override
        public boolean implementsInterface(Class<?> ifc) {
            Class<?>[] interfaces = this.getInterfaces();
            for (Class clazz : interfaces) {
                if (ifc.isInterface() && ifc.isAssignableFrom(clazz)) {
                    return true;
                }
            }
            return false;
        }
    
        @Override
        public Class<?>[] getInterfaces() {
            return new Class[] {IOther.class};
        }
    }
    

    在创建代理对象时,将拓展功能的接口set进去,所以代理对象上转型才不会报错

     org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)

    @Override
    	public Object getProxy(@Nullable ClassLoader classLoader) {
    		if (logger.isDebugEnabled()) {
    			logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
    		}
    
    		try {
    			Class<?> rootClass = this.advised.getTargetClass();
    			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
    
    			Class<?> proxySuperClass = rootClass;
    			if (ClassUtils.isCglibProxyClass(rootClass)) {
    				proxySuperClass = rootClass.getSuperclass();
    				Class<?>[] additionalInterfaces = rootClass.getInterfaces();
    				for (Class<?> additionalInterface : additionalInterfaces) {
    					this.advised.addInterface(additionalInterface);
    				}
    			}
    
    			// Validate the class, writing log messages as necessary.
    			validateClassIfNecessary(proxySuperClass, classLoader);
    
    			// Configure CGLIB Enhancer...
    			Enhancer enhancer = createEnhancer();
    			if (classLoader != null) {
    				enhancer.setClassLoader(classLoader);
    				if (classLoader instanceof SmartClassLoader &&
    						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
    					enhancer.setUseCache(false);
    				}
    			}
    			enhancer.setSuperclass(proxySuperClass);
    // 获取接口信息并且set到代理对象的接口中 enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); // Generate the proxy class and create a proxy instance. return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException | IllegalArgumentException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed throw new AopConfigException("Unexpected AOP exception", ex); } }
  • 相关阅读:
    redis
    linux systemd
    分布式高可用架构演进
    c++ 多线程 信号量简单使用
    JAVA上传文件到FTP上
    JAVA字符串去掉html代码
    jQuery判断复选框是否勾选
    SpringBoot全局异常处理
    SpringBoot统一日志打印
    JAVA加解密之DES
  • 原文地址:https://www.cnblogs.com/Hleaves/p/11337549.html
Copyright © 2020-2023  润新知