3.AOP中的IntroductionAdvisor

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

                   

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

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

示例:

1
2
3
4
5
6
7
//定义一个some类,只有doSome方法
@Component
public class Some {
    public void doSome() {
        System.out.println("do some...");
    };
}

 

1
2
3
4
//定义一个other接口,提供doOther功能
public interface IOther {
    public void doOther();
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//定义一个通知器
@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;
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//定义一个通知,要实现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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
@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);
        }
    }

 

posted on   Hleaves  阅读(1842)  评论(0编辑  收藏  举报

努力加载评论中...
点击右上角即可分享
微信分享提示