想使用AspectJ注解
定义切面需要使用@EnableAspectJAutoProxy
开启。话不多说直接开看
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* 是否强制使用Cglib
*/
boolean proxyTargetClass() default false;
/**
* 是否可以在AopContext中获取到
*/
boolean exposeProxy() default false;
}
这个注解的关键在于@Import
了一个AspectJAutoProxyRegistrar
,下面我们看一下它是干啥的?
AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
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.registerAspectJAnnotationAutoProxyCreatorIfNecessary()
:注册AspectJAnnotationAutoProxyCreator
的BeanDefinition
-
获取 @EnableAspectJAutoProxy
注解中的属性并设置到BeanDefinition
中
注册AspectJAnnotationAutoProxyCreator
public abstract class AopConfigUtils {
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
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;
}
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;
}
}
代码不能说是简单,只能说是相当容易,就是为AnnotationAwareAspectJAutoProxyCreator
定义BeanDefinition
,beanName为org.springframework.aop.config.internalAutoProxyCreator
设置注解的属性
注解中两个属性
-
proxyTargetClass
-
exposeProxy
public abstract class AopConfigUtils {
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
}
}
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
}
}
}
就是将这两个Boolean值设置到
BeanDefinition
的MutablePropertyValues
中
AspectJAnnotationAutoProxyCreator
何时为目标类创建代理
单例Bean是在初始化阶段完成Aop代理的创建,完成这项工作的类就是AspectJAnnotationAutoProxyCreator
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
//......................
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
该类何时准备好(创建好)
目标类在初始化阶段完成Aop代理,Aop代理的创建需要
AspectJAnnotationAutoProxyCreator
这个类。那必然需要其在所有目标类创建前,完成创建。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
try {
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
}
catch (BeansException ex) {
throw ex;
}
finally {
}
}
}
看一下应用上下文刷新方法。有一个地方
registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//............................
}
我们就看第一行,获取所有BeanPostProcessor
的beanName,那必然有AspectJAnnotationAutoProxyCreator
。在这一阶段,Spring应用上下文已经为我们准备好了AspectJAnnotationAutoProxyCreator
总结
本文介绍了@EnableAspectJAutoProxy
为我们开启了Aop代理的功能,其主要原理就是为我们注册了AspectJAnnotationAutoProxyCreator
这么一个BeanPostProcessor
,在Bean的初始化阶段会调用该类的postProcessAfterInitialization
完成Aop代理的创建工作。
原文始发于微信公众号(溪溪技术笔记):SpringAOP源码阅读-@EnableAspectJAutoProxy
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/207171.html