目录
@EnableAspectJAutoProxy找切面代理对象的创建代理方法的执行ExposeInvocationInterceptor#invoke环绕通知的执行前置通知的执行后置通知的执行返回后通知的执行异常通知的执行@EnableAspectJAutoProxy
@EnableAspectJAutoProxy
注解用于开启AOP功能,那么这个注解底层到底做了什么呢?
查看@EnableAspectJAutoProxy
的源码,发现它使用@Import
注解向Spring容器中注入了一个类型为AspectJAutoProxyRegistrar
的Bean:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 注入一个bean名字为org.springframework.aop.config.internalAutoProxyCreator的AspectJAwareAdvisorAutoProxyCreator AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { // proxyTargetClass为true AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { // exposeProxy为true AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } }
AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,而ImportBeanDefinitionRegistrar是spring提供的扩展点之一,主要用来向容器中注入BeanDefinition,spring会根据BeanDefinion来生成Bean。
那么AspectJAutoProxyRegistrar到底向容器中注入了什么BeanDefinion呢?
org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
@Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null); } @Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { // AnnotationAwareAspectJAutoProxyCreator return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); } @Nullable private static BeanDefinition registerOrEscalateApcAsRequired( Class cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } // 注入AspectJAwareAdvisorAutoProxyCreator RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
从源码可以发现AspectJAutoProxyRegistrar
向容器中注入了一个类型为AnnotationAwareAspectJAutoProxyCreator
的Bean。
那么AnnotationAwareAspectJAutoProxyCreator
又是干什么的呢?
AnnotationAwareAspectJAutoProxyCreator
主要实现了三个接口(由父类AbstractAutoProxyCreator
实现):
AnnotationAwareAspectJAutoProxyCreator的继承结构:
找切面
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
protected ListfindEligibleAdvisors(Class beanClass, String beanName) { /** * @see AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors() */ // 获取容器中所有的切面Advisor // 这里返回的切面中的方法已经是有序的了,先按注解顺序(Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),再按方法名称 List candidateAdvisors = findCandidateAdvisors(); // 获取所有能够作用于当前Bean上的Advisor List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); /** * @see AspectJAwareAdvisorAutoProxyCreator#extendAdvisors(java.util.List) */ // 往集合第一个位置加入了一个DefaultPointcutAdvisor extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { /** * @see AspectJAwareAdvisorAutoProxyCreator#sortAdvisors(java.util.List) */ // 这里是对切面进行排序,例如有@Order注解或者实现了Ordered接口 eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
protected ListfindCandidateAdvisors() { // Add all the Spring advisors found according to superclass rules. // 获取容器中所有的切面Advisor List advisors = super.findCandidateAdvisors(); // Build Advisors for all AspectJ aspects in the bean factory. if (this.aspectJAdvisorsBuilder != null) { // 这里还需要解析@Aspect注解,生成Advisor advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }
org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply
public static ListfindAdvisorsThatCanApply(List candidateAdvisors, Class clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List eligibleAdvisors = new ArrayList<>(); // InstantiationModelAwarePointcutAdvisorImpl for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { // IntroductionAdvisor类型为引入切面,具体类型为DeclareParentsAdvisor eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor) { // already processed continue; } // PointCut中的ClassFilter.match 匹配类 // PointCut中的MethodMatcher.match 匹配方法 if (canApply(candidate, clazz, hasIntroductions)) { // @Aspect,类型为InstantiationModelAwarePointcutAdvisorImpl eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }
代理对象的创建
代理对象的创建时机位于bean的初始化之后,因为代理对象内部还是需要去调用目标对象的方法,所以需要让目标对象实例化并完成初始化后才会创建代理对象。
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { // 先从缓存中获取代理对象 Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { // 按需生成代理对象 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. /** * @see AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(java.lang.Class, java.lang.String, org.springframework.aop.TargetSource) */ // 获取与当前Bean匹配的切面 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 创建代理 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; }
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
protected Object createProxy(Class beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } // 创建代理工厂 ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { // 进来说明proxyTargetClass=false,指定JDK代理 if (shouldProxyTargetClass(beanClass, beanName)) { // 进来这里说明BD中有个属性preserveTargetClass=true,可以BD中属性设置的优先级最高 proxyFactory.setProxyTargetClass(true); } else { // 这里会判断bean有没有实现接口,没有就只能使用CGlib evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); // 切面 proxyFactory.setTargetSource(targetSource); // 目标对象 customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 使用JDK或者CGlib创建代理对象 return proxyFactory.getProxy(getProxyClassLoader()); }
org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)
public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource()); } Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
这里主要看JDK动态代理的实现,Proxy.newProxyInstance()的第三个参数为InvocationHandler,而这里传的是this,也就是当前的类肯定实现了InvocationHandler接口。
代理方法的执行
由于是JDK动态代理,那么代理方法的调用肯定会进入InvocationHandler.invoke()方法中,这里的InvocationHandler的实现类为org.springframework.aop.framework.JdkDynamicAopProxy。
org.springframework.aop.framework.JdkDynamicAopProxy#invoke
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Object target = null; try { if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { // The target does not implement the equals(Object) method itself. return equals(args[0]); } else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // The target does not implement the hashCode() method itself. return hashCode(); } else if (method.getDeclaringClass() == DecoratingProxy.class) { // There is only getDecoratedClass() declared -> dispatch to proxy config. return AopProxyUtils.ultimateTargetClass(this.advised); } else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { // Service invocations on ProxyConfig with the proxy config... return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal; if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // Get as late as possible to minimize the time we "own" the target, // in case it comes from a pool. target = targetSource.getTarget(); // 目标对象 Class targetClass = (target != null ? target.getClass() : null); // 目标对象的类型 // Get the interception chain for this method. // 这里会对方法进行匹配,因为不是目标对象中的所有方法都需要增强 List