[spring6: IntroductionAdvisor IntroductionInterceptor]-源码分析
推荐阅读:[spring6: PointcutAdvisor & MethodInterceptor]-简单介绍
源码
IntroductionAdvisor
public interface IntroductionAdvisor extends Advisor, IntroductionInfo {ClassFilter getClassFilter();void validateInterfaces() throws IllegalArgumentException;}
DefaultIntroductionAdvisor
DefaultIntroductionAdvisor
是 Spring AOP 中的一个 IntroductionAdvisor
实现,它不仅将给定的通知(Advice
)与接口引入机制结合,还支持通过 Ordered
接口定义执行顺序。
@SuppressWarnings("serial")
public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFilter, Ordered, Serializable {private final Advice advice;private final Set<Class<?>> interfaces = new LinkedHashSet<>();private int order = Ordered.LOWEST_PRECEDENCE;public DefaultIntroductionAdvisor(Advice advice) {this(advice, (advice instanceof IntroductionInfo introductionInfo ? introductionInfo : null));}public DefaultIntroductionAdvisor(Advice advice, @Nullable IntroductionInfo introductionInfo) {Assert.notNull(advice, "Advice must not be null");this.advice = advice;if (introductionInfo != null) {Class<?>[] introducedInterfaces = introductionInfo.getInterfaces();if (introducedInterfaces.length == 0) {throw new IllegalArgumentException("IntroductionInfo defines no interfaces to introduce: " + introductionInfo);}for (Class<?> ifc : introducedInterfaces) {addInterface(ifc);}}}public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> ifc) {Assert.notNull(advice, "Advice must not be null");this.advice = advice;addInterface(ifc);}public void addInterface(Class<?> ifc) {Assert.notNull(ifc, "Interface must not be null");if (!ifc.isInterface()) {throw new IllegalArgumentException("Specified class [" + ifc.getName() + "] must be an interface");}this.interfaces.add(ifc);}@Overridepublic Class<?>[] getInterfaces() {return ClassUtils.toClassArray(this.interfaces);}@Overridepublic void validateInterfaces() throws IllegalArgumentException {for (Class<?> ifc : this.interfaces) {if (this.advice instanceof DynamicIntroductionAdvice dynamicIntroductionAdvice &&!dynamicIntroductionAdvice.implementsInterface(ifc)) {throw new IllegalArgumentException("DynamicIntroductionAdvice [" + this.advice + "] " +"does not implement interface [" + ifc.getName() + "] specified for introduction");}}}@Overridepublic ClassFilter getClassFilter() {return this;}@Overridepublic boolean matches(Class<?> clazz) {return true;}// ...
}
DeclareParentsAdvisor
DeclareParentsAdvisor
是 Spring AOP 中用于“引介”(Introduction)的一个特殊 Advisor,它允许在不修改目标类的情况下,声明性地为其代理对象引入一个新的接口,并由独立的委托对象提供该接口的实现。
// @DeclareParents
public class DeclareParentsAdvisor implements IntroductionAdvisor {private final Advice advice;private final Class<?> introducedInterface;private final ClassFilter typePatternClassFilter;public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> defaultImpl) {this(interfaceType, typePattern, new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));}public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Object delegateRef) {this(interfaceType, typePattern, new DelegatingIntroductionInterceptor(delegateRef));}private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, IntroductionInterceptor interceptor) {this.advice = interceptor;this.introducedInterface = interfaceType;// Excludes methods implemented.ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);ClassFilter exclusion = (clazz -> !this.introducedInterface.isAssignableFrom(clazz));this.typePatternClassFilter = ClassFilters.intersection(typePatternFilter, exclusion);}@Overridepublic ClassFilter getClassFilter() {return this.typePatternClassFilter;}@Overridepublic void validateInterfaces() throws IllegalArgumentException {// Do nothing}@Overridepublic Advice getAdvice() {return this.advice;}@Overridepublic Class<?>[] getInterfaces() {return new Class<?>[] {this.introducedInterface};}}
IntroductionInterceptor
public interface IntroductionInterceptor extends MethodInterceptor, DynamicIntroductionAdvice {}
DelegatingIntroductionInterceptor
DelegatingIntroductionInterceptor
是 Spring AOP 中一个方便的基类,用于实现引介(Introduction),它通过将引入接口的方法调用** “委托” **给一个独立的(或它自身作为)实现对象来处理,从而简化了引介拦截器的编写。
@SuppressWarnings("serial")
public class DelegatingIntroductionInterceptor extends IntroductionInfoSupport implements IntroductionInterceptor {@Nullableprivate Object delegate;public DelegatingIntroductionInterceptor(Object delegate) {init(delegate);}protected DelegatingIntroductionInterceptor() {init(this);}private void init(Object delegate) {Assert.notNull(delegate, "Delegate must not be null");this.delegate = delegate;implementInterfacesOnObject(delegate);// We don't want to expose the control interfacesuppressInterface(IntroductionInterceptor.class);suppressInterface(DynamicIntroductionAdvice.class);}@Override@Nullablepublic Object invoke(MethodInvocation mi) throws Throwable {if (isMethodOnIntroducedInterface(mi)) {Object retVal = AopUtils.invokeJoinpointUsingReflection(this.delegate, mi.getMethod(), mi.getArguments());if (retVal == this.delegate && mi instanceof ProxyMethodInvocation pmi) {Object proxy = pmi.getProxy();if (mi.getMethod().getReturnType().isInstance(proxy)) {retVal = proxy;}}return retVal;}return doProceed(mi);}@Nullableprotected Object doProceed(MethodInvocation mi) throws Throwable {// If we get here, just pass the invocation on.return mi.proceed();}}
DelegatePerTargetObjectIntroductionInterceptor
DelegatePerTargetObjectIntroductionInterceptor
是一个引介拦截器,它为每个被代理的目标对象维护一个独立的委托实例(即拥有独立状态),从而确保引介的接口行为是针对每个目标对象特有的,而不是共享状态
@SuppressWarnings("serial")
public class DelegatePerTargetObjectIntroductionInterceptor extends IntroductionInfoSupportimplements IntroductionInterceptor {private final Map<Object, Object> delegateMap = new WeakHashMap<>();private final Class<?> defaultImplType;private final Class<?> interfaceType;public DelegatePerTargetObjectIntroductionInterceptor(Class<?> defaultImplType, Class<?> interfaceType) {this.defaultImplType = defaultImplType;this.interfaceType = interfaceType;Object delegate = createNewDelegate();implementInterfacesOnObject(delegate);suppressInterface(IntroductionInterceptor.class);suppressInterface(DynamicIntroductionAdvice.class);}@Override@Nullablepublic Object invoke(MethodInvocation mi) throws Throwable {if (isMethodOnIntroducedInterface(mi)) {Object delegate = getIntroductionDelegateFor(mi.getThis());Object retVal = AopUtils.invokeJoinpointUsingReflection(delegate, mi.getMethod(), mi.getArguments());if (retVal == delegate && mi instanceof ProxyMethodInvocation pmi) {retVal = pmi.getProxy();}return retVal;}return doProceed(mi);}@Nullableprotected Object doProceed(MethodInvocation mi) throws Throwable {// If we get here, just pass the invocation on.return mi.proceed();}private Object getIntroductionDelegateFor(@Nullable Object targetObject) {synchronized (this.delegateMap) {if (this.delegateMap.containsKey(targetObject)) {return this.delegateMap.get(targetObject);}else {Object delegate = createNewDelegate();this.delegateMap.put(targetObject, delegate);return delegate;}}}private Object createNewDelegate() {try {return ReflectionUtils.accessibleConstructor(this.defaultImplType).newInstance();}catch (Throwable ex) {throw new IllegalArgumentException("Cannot create default implementation for '" +this.interfaceType.getName() + "' mixin (" + this.defaultImplType.getName() + "): " + ex);}}}
实战
public interface Versioned {String getVersion();void setVersion(String version);}
public class ProductService {public void getProduct(String productId) {System.out.println("获取产品信息: " + productId);}public void updateProduct(String productId, int quantity) {System.out.println("更新产品信息: " + productId + ", 数量: " + quantity);}
}
public class VersionIntroductionInterceptor implements IntroductionInterceptor {private String serviceVersion = "1.0.0"; // 默认版本号@Overridepublic boolean implementsInterface(Class<?> intf) {return intf.isAssignableFrom(Versioned.class);}@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {if (implementsInterface(invocation.getMethod().getDeclaringClass())) {if (invocation.getMethod().getName().equals("getVersion")) {return serviceVersion;} else if (invocation.getMethod().getName().equals("setVersion")) {this.serviceVersion = (String) invocation.getArguments()[0];return null;}}return invocation.proceed();}public String getVersion() {throw new UnsupportedOperationException("This method is handled by the interceptor.");}public void setVersion(String version) {throw new UnsupportedOperationException("This method is handled by the interceptor.");}
}
public class Application {public static void main(String[] args) {ProductService targetService = new ProductService();DefaultIntroductionAdvisor introductionAdvisor = new DefaultIntroductionAdvisor(new VersionIntroductionInterceptor());ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.setTarget(targetService);proxyFactory.addInterface(Versioned.class); proxyFactory.setProxyTargetClass(true); //CGLIBproxyFactory.addAdvisor(introductionAdvisor); // 介入增强ProductService productServiceProxy = (ProductService) proxyFactory.getProxy();Versioned versionedProxy = (Versioned) proxyFactory.getProxy();// 获取产品信息: BOOK001// 当前产品版本: 1.0.0productServiceProxy.getProduct("BOOK001");System.out.println("当前产品版本: " + versionedProxy.getVersion());// 更新产品信息: BOOK001, 数量: 10// 当前产品版本: 2.0.0productServiceProxy.updateProduct("BOOK001", 10);versionedProxy.setVersion("2.0.0");System.out.println("当前产品版本: " + versionedProxy.getVersion());}
}