spring-aop源码分析(2)_AnnotationAwareAspectJAutoProxyCreator后置处理器
创始人
2024-04-17 23:40:19
0

本文将通过阅读AnnotationAwareAspectJAutoProxyCreator后置处理器的源码,分析其解析AOP通知、匹配切入点和创建AOP代理的流程。

入口

AnnotationAwareAspectJAutoProxyCreator是一个BeanPostProcessor实现,他在容器进行initializeBean的时候被调用:

在这里插入图片描述

核心的BeanPostProcessor方法实现都在其父类AbstractAutoProxyCreator中实现。

wrapIfNecessary方法

在其父类AbstractAutoProxyCreator的postProcessAfterInitialization方法中。

核心功能:

  • 查找AOP Advisor
  • 创建AOP代理
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {// 最开始是一些是否需要AOP的判断,如果不需要或者已经创建代理,则直接返回了// Create proxy if we have advice.// 查找AOP AdvisorObject[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);// 创建AOP代理Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;
}

getAdvicesAndAdvisorsForBean方法

查找AOP Advisor

protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, @Nullable TargetSource targetSource) {List advisors = findEligibleAdvisors(beanClass, beanName);if (advisors.isEmpty()) {return DO_NOT_PROXY;}return advisors.toArray();
}// Find all eligible Advisors for auto-proxying this class.
protected List findEligibleAdvisors(Class beanClass, String beanName) {// 此处分为两部分:// 1. 查找Spring容器里面注入的Advisor// 2. 解析所有的AspectJ AOP并创建Advisor// 实现逻辑在AnnotationAwareAspectJAutoProxyCreator类中List candidateAdvisors = findCandidateAdvisors();// Search the given candidate Advisors to find all Advisors that can apply to the specified bean.List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);// Add an ExposeInvocationInterceptor to the beginning of the advice chain.// This additional advice is needed when using AspectJ pointcut expressions and // when using AspectJ-style advice.extendAdvisors(eligibleAdvisors);if (!eligibleAdvisors.isEmpty()) {eligibleAdvisors = sortAdvisors(eligibleAdvisors);}return eligibleAdvisors;
}// AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors
protected List findCandidateAdvisors() {// Add all the Spring advisors found according to superclass rules.// 查找Spring容器里面注入的Advisor,代码就不再展开记录List advisors = super.findCandidateAdvisors();// Build Advisors for all AspectJ aspects in the bean factory.// 解析所有的AspectJ AOP并创建Advisorif (this.aspectJAdvisorsBuilder != null) {advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());}return advisors;
}

过滤当前Bean可用Advisor

findAdvisorsThatCanApply方法用于过滤可用Advisor:

protected List findAdvisorsThatCanApply(List candidateAdvisors, Class beanClass, String beanName) {ProxyCreationContext.setCurrentProxiedBeanName(beanName);try {return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);} finally {ProxyCreationContext.setCurrentProxiedBeanName(null);}
}

AopUtils.findAdvisorsThatCanApply方法:

// Determine the sublist of the candidateAdvisors list that is applicable to the given class.
public static List findAdvisorsThatCanApply(List candidateAdvisors, Class clazz) {List eligibleAdvisors = new ArrayList<>();for (Advisor candidate : candidateAdvisors) {if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {eligibleAdvisors.add(candidate);}}boolean hasIntroductions = !eligibleAdvisors.isEmpty();for (Advisor candidate : candidateAdvisors) {if (candidate instanceof IntroductionAdvisor) {// already processedcontinue;}if (canApply(candidate, clazz, hasIntroductions)) {eligibleAdvisors.add(candidate);}}return eligibleAdvisors;
}public static boolean canApply(Advisor advisor, Class targetClass, boolean hasIntroductions) {if (advisor instanceof IntroductionAdvisor) {return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);} else if (advisor instanceof PointcutAdvisor) {PointcutAdvisor pca = (PointcutAdvisor) advisor;// 使用pointcut判断return canApply(pca.getPointcut(), targetClass, hasIntroductions);} else {return true;}
}

排序

在查找Advisor集的过程中,有一步是Advisor集排序:

protected List findEligibleAdvisors(Class beanClass, String beanName) {List candidateAdvisors = findCandidateAdvisors();List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);extendAdvisors(eligibleAdvisors);if (!eligibleAdvisors.isEmpty()) {// 排序eligibleAdvisors = sortAdvisors(eligibleAdvisors);}return eligibleAdvisors;
}protected List sortAdvisors(List advisors) {List partiallyComparableAdvisors = new ArrayList<>(advisors.size());for (Advisor advisor : advisors) {partiallyComparableAdvisors.add(new PartiallyComparableAdvisorHolder(advisor, DEFAULT_PRECEDENCE_COMPARATOR));}List sorted = PartialOrder.sort(partiallyComparableAdvisors);if (sorted != null) {List result = new ArrayList<>(advisors.size());for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {result.add(pcAdvisor.getAdvisor());}return result;} else {return super.sortAdvisors(advisors);}
}

核心的排序逻辑都在DEFAULT_PRECEDENCE_COMPARATOR中,他是一个Comparator实现:

public int compare(Advisor o1, Advisor o2) {int advisorPrecedence = this.advisorComparator.compare(o1, o2);// 如果advisorComparator比较结果相同,将使用AspectJ相关的方法排序,此部分不分析if (advisorPrecedence == SAME_PRECEDENCE && declaredInSameAspect(o1, o2)) {advisorPrecedence = comparePrecedenceWithinAspect(o1, o2);}return advisorPrecedence;
}

advisorComparator也是一个Comparator实现,他内部有一些从Ordered实现方法、Order注解获取顺序的逻辑,此处不展开分析,了解即可。

创建AOP代理

// 创建AOP代理
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

createProxy入口方法

protected Object createProxy(Class beanClass, String beanName,Object[] specificInterceptors, TargetSource targetSource) {// Expose the given target class for the specified bean, if possible.if (this.beanFactory instanceof ConfigurableListableBeanFactory) {AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);}ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.copyFrom(this);if (!proxyFactory.isProxyTargetClass()) {if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {evaluateProxyInterfaces(beanClass, proxyFactory);}}// 构建AOP通知Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);proxyFactory.addAdvisors(advisors);proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}// 创建代理return proxyFactory.getProxy(getProxyClassLoader());
}// 构建AOP通知
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {Advisor[] commonInterceptors = resolveInterceptorNames();List allInterceptors = new ArrayList<>();if (specificInterceptors != null) {allInterceptors.addAll(Arrays.asList(specificInterceptors));if (commonInterceptors.length > 0) {// 不重要}}Advisor[] advisors = new Advisor[allInterceptors.size()];for (int i = 0; i < allInterceptors.size(); i++) {advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));}return advisors;
}
 

proxyFactory.getProxy方法里面判断使用Cglib还是JdkProxy创建代理:

public Object getProxy(@Nullable ClassLoader classLoader) {return createAopProxy().getProxy(classLoader);
}public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {Class targetClass = config.getTargetClass();if (targetClass == null) {// throw exception}if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);}return new ObjenesisCglibAopProxy(config);} else {return new JdkDynamicAopProxy(config);}
}

Cglib代理

从上面的代码可以看到,Cglib代理是使用ObjenesisCglibAopProxy实现类创建的。

继承关系是这样的:

AopProxy|-- CglibAopProxy|-- ObjenesisCglibAopProxy

Spring Cglib示例

下面代码演示如何是Spring Cglib创建一个代理类对象:

public static void main(String[] args) throws InstantiationException, IllegalAccessException {ClassLoader classLoader = CglibTest.class.getClassLoader();Enhancer enhancer = createEnhancer();// 设置目标类型enhancer.setSuperclass(LogService.class);enhancer.setClassLoader(classLoader);enhancer.setUseCache(false);enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));// callback集Callback[] callbacks = new Callback[]{new MyMethodInterceptor()};Class[] types = new Class[callbacks.length];for (int x = 0; x < types.length; x++) {types[x] = callbacks[x].getClass();}enhancer.setCallbackTypes(types);// 创建代理类并实例化Class proxyClass = enhancer.createClass();Object proxyInstance = proxyClass.newInstance();((Factory) proxyInstance).setCallbacks(callbacks);LogService o = (LogService) proxyInstance;o.testServiceLog();
}protected static Enhancer createEnhancer() {return new Enhancer();
}private static class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object enhancedConfigInstance, Method beanMethod,Object[] beanMethodArgs, MethodProxy cglibMethodProxy) throws Throwable {System.out.printf("MyMethodInterceptor %s args: %s\n",beanMethod.getName(), Arrays.toString(beanMethodArgs));return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);}
}

CglibAopProxy.getProxy实现

public Object getProxy(ClassLoader classLoader) {try {Class rootClass = this.advised.getTargetClass();Class proxySuperClass = rootClass;if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {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);enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));// 通过advisor创建cglib代理callbackCallback[] 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 aboveenhancer.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} catch (Throwable ex) {// throw new AopConfigException}
}

getCallbacks

创建cglib callback对象,最核心的就是使用spring aop advisor创建了一个DynamicAdvisedInterceptor对象,让其作为代理对象的处理逻辑。

DynamicAdvisedInterceptor这个类会在后续解析AOP执行流程时再做介绍。

下图就是该方法封装DynamicAdvisedInterceptor对象的结构:

  • target - 封装原始的Bean对象
  • advisors - spring aop advisor集

在这里插入图片描述

createProxyClassAndInstance

这个方法在ObjenesisCglibAopProxy类实现:

protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {// Generate a new class if necessary and return it without creating a new instance.// This ignores any callbacks that have been set.// To create a new instance you will have to use reflection,// and methods called during the constructor will not be intercepted.// To avoid this problem, use the multi-arg create method.// 生成代理类Class proxyClass = enhancer.createClass();Object proxyInstance = null;// 创建proxyInstance代理对象,实际上就是使用反射创建一个proxyClass的实例,代码省略// 设置callback代理拦截((Factory) proxyInstance).setCallbacks(callbacks);return proxyInstance;
}

Cglib生成代理类(暂时不分析)

不太懂,暂时不分析。

JDK代理

JDK代理示例

public static void main(String[] args) {LogService logService = new LogServiceImpl();Object proxyInstance = Proxy.newProxyInstance(SpringJdkProxyDemo.class.getClassLoader(),new Class[]{LogService.class},new MyInvocationHandler(logService));LogService o = (LogService) proxyInstance;o.log();
}static class MyInvocationHandler implements InvocationHandler {private final Object object;public MyInvocationHandler(Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.printf("MyInvocationHandler %s args: %s\n",method.getName(), Arrays.toString(args));return method.invoke(this.object, args);}
}interface LogService {void log();
}static class LogServiceImpl implements LogService {@Overridepublic void log() {System.out.println("LogServiceImpl.log()");}
}

JdkDynamicAopProxy.getProxy

public Object getProxy(ClassLoader classLoader) {Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

代码比较简单,就是使用java的Proxy创建代理对象,第三个参数传递的是this,因为JdkDynamicAopProxy实现了InvocationHandler接口。

小结

在本文中,我们了解到了AnnotationAwareAspectJAutoProxyCreator后置处理器如何为Bean对象解析Advisor集、匹配可用Advisor集和创建代理对象的过程。

后续,我们将继续阅读CglibAopProxy和JdkDynamicAopProxy的代码,分析Spring AOP的执行流程。

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...