Spring 注解是什么_AOP
该系列学习笔记均是笔者通过学习某站雷丰阳老师的相关课程并结合 spring 2.* 版本源码自行整理出来的。如果有叙述不到位或者有误的地方烦请各位读者评论区给予指正,大家共同学习。
AOP:即在程序运行期间动态的将某段代码切入到指定方法的指定位置进行运行的编程方式
一、使用方式
- 编写目标类和切面类,并使用注解标识切面类以及对应的通知方法
/** * 目标类 MathCalculator * 目标方法 div() */ public class MathCalculator { public int div(int i, int j) { System.err.println("MathCalculator::add()"); return i / j; } } /** * 使用 @Aspect 标识该类为切面类 * * 通知方法的执行顺序: * try { * @Before * method.invoke(obj, args); * @AfterReturning * } catch (Exception e) { * @AfterThrowing * } finally { * @After * } * * 正常执行: * @Before(前置通知) -> @After(后置通知) -> @AfterReturning(返回通知) * 异常执行: * @Before(前置通知) -> @After(后置通知) -> @AfterThrowing(异常通知) */ @Aspect public class LogAspects { // 使用 @Pointcut() 定义切入点表达式 @Pointcut(value = "execution(* com.blackpearl.aopconfig.MathCalculator.div(..))") public void pointCut(){} // 前置通知 @Before(value = "pointCut()") public void logStart(JoinPoint joinPoint) { System.err.println(joinPoint.getSignature().getName() + " @Before"); } // 后置通知 @After(value = "pointCut()") public void logEnd(JoinPoint joinPoint) { System.err.println(joinPoint.getSignature().getName() + " @After"); } // 返回通知 @AfterReturning(value = "pointCut()", returning = "result") public void logReturning(JoinPoint joinPoint, Integer result) { System.err.println(joinPoint.getSignature().getName() + " @AfterReturning Result: " + result); } // 异常通知 @AfterThrowing(value = "pointCut()", throwing = "exception") public void logThrowing(JoinPoint joinPoint, Exception exception) { System.err.println(joinPoint.getSignature().getName() + " @AfterThrowing Exception: " + exception.getMessage()); } }
- 通过 Spring 配置类注入目标类和切面类,同时开启基于注解的 AOP 模式
/** * @EnableAspectJAutoProxy 开启基于注解的 AOP */ @EnableAspectJAutoProxy @Configuration public class SpringAOPConfig { // 注入目标类 @Bean public MathCalculator mathCalculator() { return new MathCalculator(); } // 注入切面类 @Bean public LogAspects logAspects() { return new LogAspects(); } }
二、原理解析
注解形式的 AOP 需要使用 @EnableAspectJAutoProxy 注解
-
@EnableAspectJAutoProxy
@Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy {}
-
AspectJAutoProxyRegistrar 类会向容器中注入 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 类,该类在容器中的 name 属性为 org.springframework.aop.config.internalAutoProxyCreator
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary( AnnotationAwareAspectJAutoProxyCreator.class, registry, (Object)null); ... } }
public abstract class AopConfigUtils { @Nullable private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { // 判断 Spring 容器中是否已经存在 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) { BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator"); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } else { RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", -2147483648); beanDefinition.setRole(2); // 不存在,使用 BeanDefinitionRegistry::registerBeanDefinition 进行注入 // org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 对应的 name 属性为 org.springframework.aop.config.internalAutoProxyCreator registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition); return beanDefinition; } } }
-
AspectJAutoProxyRegistrar 类会向容器中注入 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 类,该类在容器中的 name 属性为 org.springframework.aop.config.internalAutoProxyCreator
-
AnnotationAwareAspectJAutoProxyCreator 类根据继承树,该类 implements InstantiationAwareBeanPostProcessor, BeanFactoryAware
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { @Nullable Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException; boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException; }
public class AnnotationAwareAspectJAutoProxyCreator implements InstantiationAwareBeanPostProcessor, BeanFactoryAware { @Nullable private AspectJAdvisorFactory aspectJAdvisorFactory; @Nullable private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder; @Nullable private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper; @Nullable private BeanFactory beanFactory; // BeanFactoryAware::setBeanFactory @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; initBeanFactory((ConfigurableListableBeanFactory) beanFactory); } @Override protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory); if (this.aspectJAdvisorFactory == null) { this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory); } this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory); } // InstantiationAwareBeanPostProcessor::postProcessBeforeInstantiation @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } return null; } // InstantiationAwareBeanPostProcessor::postProcessAfterInstantiation @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) { return true; } // BeanPostProcessor::postProcessBeforeInitialization @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } // BeanPostProcessor::postProcessAfterInitialization @Override 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; } }
由于 AnnotationAwareAspectJAutoProxyCreator 类 implements BeanPostProcessor,因此会在容器中 Bean 对象初始化方法之前/后工作,具体流程如下:
-
创建容器,传入自定义配置类,刷新容器
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { this(); register(componentClasses); refresh(); }
-
AbstractApplicationContext::refresh() 刷新容器
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { try { ... // 注册 BeanPostProcessor 用于拦截容器中 Bean 对象的创建 registerBeanPostProcessors(beanFactory); ... } catch (BeansException ex) {} finally {} } } }
-
registerBeanPostProcessors(beanFactory) 注册 BeanPostProcessor
该方法会将容器中需要注入的 BeanPostProcessor 按等级按批次进行注册,之前注册的 BeanPostProcessor 可以为之后注册的 BeanPostProcessor 提供 postProcessBeforeInitialization / postProcessAfterInitialization 回调函数public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // Separate between BeanPostProcessors that implement PriorityOrdered, Ordered, and the rest. List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); // First, register the BeanPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String ppName : orderedPostProcessorNames) { // AnnotationAwareAspectJAutoProxyCreator implements Ordered // 因此 AnnotationAwareAspectJAutoProxyCreator 会在此进行注册 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); // 将注册的 AnnotationAwareAspectJAutoProxyCreator 添加到 beanFactory 中 => 进入容器 registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
-
所谓注册 BeanPostProcessor 即创建对应的 BeanPostProcessor 并注入容器
BeanPostProcessor 的创建流程位于 AbstractAutowireCapableBeanFactory::doCreateBeanpublic abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; // 如果 Bean 对象为单实例 if (mbd.isSingleton()) { // 先尝试从缓存中获取 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 获取失败则执行 Bean 对象构造方法 => 创建 Bean 对象 instanceWrapper = createBeanInstance(beanName, mbd, args); } // Initialize the bean instance. Object exposedObject = bean; try { // 为创建的 Bean 对象进行属性赋值 populateBean(beanName, mbd, instanceWrapper); // 执行 Bean 对象的初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) {} // Register bean as disposable. try { // 将单实例 Bean 对象加入到 list 中,在容器销毁时会调用这个 list 中所有 Bean 对象的销毁方法 registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) {} return exposedObject; } protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { // 由于 AnnotationAwareAspectJAutoProxyCreator implements BeanFactoryAware,因此需要回调 BeanFactoryAware::setBeanFactory() 方法缓存 beanFactory invokeAwareMethods(beanName, bean); Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 执行容器中所有的 BeanPostProcessor 执行其 postProcessBeforeInitialization 方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 执行 Bean 对象的初始化方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) {} if (mbd == null || !mbd.isSynthetic()) { // 执行容器中所有的 BeanPostProcessor 执行其 postProcessAfterInitialization 方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } }
-
registerBeanPostProcessors(beanFactory) 注册 BeanPostProcessor
至此,AnnotationAwareAspectJAutoProxyCreator 类已经加入容器
-
创建容器,传入自定义配置类,刷新容器
-
以后,容器再创建 Bean 对象之前,会先调用 AnnotationAwareAspectJAutoProxyCreator::postProcessBeforeInstantiation 方法
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { RootBeanDefinition mbdToUse = mbd; try { // 尝试通过容器中所有的 BeanPostProcessor 获取 Bean 的代理对象 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { // 获取成功直接 return return bean; } } catch (Throwable ex) {} try { // 获取失败才开始创建 Bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {} catch (Throwable ex) {} }
@Nullable protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { // 尝试调用容器中所有的 BeanPostProcessor::postProcessBeforeInstantiation bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } return bean; } @Nullable protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { // 仅 implements InstantiationAwareBeanPostProcessor 的 BeanPostProcessor 才有 postProcessBeforeInstantiation 方法 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 调用 InstantiationAwareBeanPostProcessor::postProcessBeforeInstantiation Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
public class AnnotationAwareAspectJAutoProxyCreator implements InstantiationAwareBeanPostProcessor, BeanFactoryAware { @Nullable private AspectJAdvisorFactory aspectJAdvisorFactory; @Nullable private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder; @Nullable private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper; @Nullable private BeanFactory beanFactory; // BeanFactoryAware::setBeanFactory @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; initBeanFactory((ConfigurableListableBeanFactory) beanFactory); } @Override protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory); if (this.aspectJAdvisorFactory == null) { this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory); } this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory); } // InstantiationAwareBeanPostProcessor::postProcessBeforeInstantiation @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { // 判断当前 Bean 是否属于需要增强的 Bean 对象(即需要被动态插入执行代码的 Bean) if (this.advisedBeans.containsKey(cacheKey)) { return null; } // isInfrastructureClass 用于判断当前 Bean 是否 implements Advice / Pointcut / Advisor / AopInfrastructureBean 或 指定了 @Aspect 注解 // shouldSkip 用于判断容器中的增强器(即为通知方法)的类型 if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } return null; } // 执行完容器中所有后置处理器的 postProcessBeforeInstantiation 方法后,会进行 Bean 对象的创建,在执行完 Bean 对象的初始化方法后,会执行 BeanPostProcessor::postProcessAfterInitialization 方法 // BeanPostProcessor::postProcessAfterInitialization @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { // 如果该 Bean 对象属于需要增强的 Bean 对象则向容器注入该 Bean 对象的代理对象 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { // 获取当前 Bean 对象需要使用的增强器(即需要动态插入到该 Bean 对象目标方法执行前后的通知方法) Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { // 缓存当前 Bean 为需要增强的 Bean 对象 this.advisedBeans.put(cacheKey, Boolean.TRUE); // 创建当前 Bean 的代理对象,Spring 通过判断该 Bean 是否实现接口决定创建 JdkDynamicAopProxy / ObjenesisCglibAopProxy 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; } }
至此,对于需要增强的 Bean 对象,Spring 为其创建了代理对象同时也保存了该 Bean 对象需要使用的所有增强器(即通知方法)
-
以后,对于需要增强的 Bean 对象,Spring 使用其创建的代理对象,其中保存了增强器(即通知方法)和目标方法的详细信息
针对每一个增强器,Spring 将其包装为方法拦截器 MethodInterceptor,组成 list 集合
由图可见,list 集合中元素顺序为 @AfterThrowing / @AfterReturning / @After / @Before,集合中拦截器执行顺序为逆序执行,并且在执行目标方法时如果报错,拦截器调用链会将异常抛出public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable { @Override public Object invoke(MethodInvocation mi) throws Throwable { Object retVal = mi.proceed(); // 拦截器使用 proceed 进行方法调用,如果目标方法抛异常,则此处会出现异常 // 异常会被抛出,this.advice.afterReturning() 不会执行,即不会执行 @AfterReturning 返回通知方法 this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; } }
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable { @Override public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); // 出现异常 } catch (Throwable ex) { if (shouldInvokeOnThrowing(ex)) { // 出现异常会调用该方法执行 @AfterThrowing 异常通知方法 invokeAdviceMethod(getJoinPointMatch(), null, ex); } throw ex; } } }
本文地址:https://blog.csdn.net/qq_43415605/article/details/107478432
上一篇: nginx~对没有定义service_name的三级域名进行过滤
下一篇: 手写快读