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); } }