基础
这里回顾一下前期学习的AOP知识,其中AOP的核心知识点就是2个:AspectJ表达式、通知;
其中通知分为5类:before前置通知、after后置通知、afterrunning返回通知、afterthrowing异常通知、around环绕通知;
这5种类型的通知也对应着5种类型的注解:
@Before前置通知、@After后置通知、@AfterReturning返回通知、@AfterThrowing异常通知、@Around环绕通知;
这5个注解的参数,就是切入表达式,这里可以参考之前写的案例;
下面总结一下,基于注解来使用AOP的流程:
①在@Configuration注解的配置类中,对类添加@EnableAspectJAutoProxy注解,来声明启动AOP;
②在切面类中对类使用@Aspect注解,来声明当前类是切面类;
③在切面类中,使用@Before、@After、@AfterReturning、@AfterThrowing、@Around注解来声明不同的通知,其中重点遵循切点表达式;
④配合JoinPoint对象来获取被切方法的信息,注意:JoinPoint一定出现在参数表的第一位;
⑤把切面类、被切面的类都要放入IOC容器中,这样才能让AOP生效;
@EnableAspectJAutoProxy注解实现原理
看一下注解源码:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({AspectJAutoProxyRegistrar.class}) public @interface EnableAspectJAutoProxy { boolean proxyTargetClass() default false; boolean exposeProxy() default false; } |
EnableAspectJAutoProxy注解引入了AspectJAutoProxy-
Registrar类,而该类实现了ImportBeanDefinitionRegistrar接口,通过该接口的registerBeanDefinitions方法来向容器中注册;
在AspectJAutoProxyRegistrar类代码如下:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { AspectJAutoProxyRegistrar() { } public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } } |
源码中重要的一行在于AopConfigUtils.registerAspectJ-
AnnotationAutoProxyCreatorIfNecessary(registry);通过继续查看源代码可知,该方法注册的类是AnnotationAwareAspectJAuto-
ProxyCreator;
AnnotationAwareAspectJAutoProxyCreator--继承-->
AspectJAwareAdvisorAutoProxyCreator--继承-->
AbstractAdvisorAutoProxyCreator--继承-->
AbstractAutoProxyCreator--继承-->
ProxyProcessorSupport,且实现了BeanFactoryAware接口、
SmartInstantiationAwareBeanPostProcessor接口;
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } } |
public interface BeanFactoryAware extends Aware { |
通过查看源代码可知:
实现类情况 | BeanFactoryAware-setBeanFactory方法 | BeanPostProcessor -postProcessBefore Initialization方法 | BeanPostProcessor-postProcessAfter Initialization方法 |
AbstractAutoProxyCreator | 实现 | 实现 | 实现 |
AbstractAdvisorAutoProxyCreator | 完成(且调用了initBeanFactory方法) | 未实现 | 未实现 |
AnnotationAwareAspectJAutoProxyCreator | 完成(实现的是initBeanFactory 方法) |
|
|
因此,@EnableAspectJAutoProxy注解实现原理只需关心上面3个类即可;
@Resource和@Inject
@Resource:Spring支持JAVA规范自带的JSR250规范,其效果跟@Autowired类似,使用形式如:@Resource(name=”xxxx”),该注解不支持@Primary注解,也不支持@Autowired(required=false);
@Inject:Spring支持JAVA规范自带的JSR330规范,其效果跟@Autowired类似,需要javax.inject包支持,使用形式如:@Inject