Spring源码分析系列(一)--通过@EnableAspectJAutoProxy分析AOP加载过程
AOP是面向切面编程,是相对于OOP面向对象编程而言的。Spring的AOP的存在的目的是为了解耦。AOP可以让一组类共享相同的行为。在OOP中只能通过继承类和实现接口来实现,但是这样的缺点是会使代码的耦合度增加,且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP的出现弥补了OOP的不足。
使用@EnableAspectJAutoProxy注解开启Spring对AspectJ的支持。
添加@EnableAspectJAutoProxy注解,表示开启AOP代理自动配置,如果使用@EnableAspectJAutoProxy注解,表示使用cglib进行代理对象的生成。设置@EnableAspectJAutoProxy(exposeProxy=true)表示通过AOP框架暴露该代理对象,aopContext能够访问。
下面看一下@EnableAspectJAutoProxy这个类的源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies. The default is {@code false}.
*/
// true--使用CGLIB基于类创建代理,false--使用java接口创建代理
boolean proxyTargetClass() default false;
/**
* Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
* for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
* Off by default, i.e. no guarantees that {@code AopContext} access will work.
* @since 4.3.1
*/
// 是否通过aop矿建暴露该代理对象,aopContext能够访问
boolean exposeProxy() default false;
}
通过上面的代码可以看出@EnableAspectJAutoProxy把AspectJAutoProxyRegistrar.class对象导入到了容器中。利用AspectJAutoProxyRegistrar给容器中注册了一个AnnotationAwareAspectJAutoProxyCreator。
AspectJAutoProxyRegistrar
AspectJAutoProxyRegistrar类中的registerBeanDefinitions方法主要实现了两个功能:
- 1.注册AnnotationAwareAspectJAutoProxyCreator
- 2.获取@EnableAspectJAutoProxy注解的属性信息
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注册AnnotationAwareAspectJAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//获取@EnableAspectJAutoProxy注解的属性信息
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata,EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
1.注册AnnotationAwareAspectJAutoProxyCreator
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
//注册AnnotationAwareAspectJAutoProxyCreator
@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");
//判断是否包含目标bean
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);
//将beanDefinition注册到registry中,name为AUTO_PROXY_CREATOR_BEAN_NAME
//AUTO_PROXY_CREATOR_BEAN_NAME = org.springframework.aop.config.internalAutoProxyCreator
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。