Spring AspectJ AOP Bean创建分析
1.@EnableAspectJAutoProxy
//EnableAspectJAutoProxy.java
@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}.
*/
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
*/
boolean exposeProxy() default false;
}
上述代码是springAop源码的最主要的注解;下边我们来分析下AspectJAutoProxyRegistrar.java
2.AspectJAutoProxyRegistrar
//AspectJAutoProxyRegistrar.java
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) {
//如果需要注册AspectJ代理自动创建器
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
由上述代码可知,AspectJAutoProxyRegistrar.java即AspectJ自动代理注册组件,实现了ImportBeanDefinitionRegistrar接口,也就是自定义导入组件。
我们在AspectJAutoProxyRegistrar.java的45行打个断点,进行调试
2处加入了AnnotationAwareAspectJAutoProxyCreator.java 即AspectJ注解自动代理创建器,稍后我们在分析
接下来我们看registerOrEscalateApcAsRequired()方法:
//AspectJAutoProxyRegistrar.java
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//<1>判断容器中有没有org.springframework.aop.config.internalAutoProxyCreator
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;
}
//<2>如果没有在bean注册org.springframework.aop.config.internalAutoProxyCreator
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;
}
<1>由AUTO_PROXY_CREATOR_BEAN_NAME 可知肯定是判断是否容器中有internalAutoProxyCreator的bean
<2>没有就创建一个
3.AnnotationAwareAspecttJAutoProxyCreator
由类图继承关系可知AnnotationAwareAspecttJAutoProxyCreator的父类AbstractAutoProxyCreator实现了bean后置处理器和BeanfactoryAware。
3.1AnnotationAwareAspecttJAutoProxyCreator分析
分别在父类ProxyProcessorSupport 204行和241行打断点,因为都是和创建bean的相关方法。
父类AbstractAdvisorAutoProxyCreator 如下图所示打好断点
AnnotationAwareAspectJAutoProxyCreator 75行打好断点
调试开始:
查看调用栈:
3.1.1 刷新容器
3.1.2 注册拦截Bean创建的Bean处理器。
3.1.3 注册bean后置处理器
3.1.4 获取AnnotationAwareAspecttJAutoProxyCreator后置处理器
3.1.5 获取bean
3.1.6 第一次获取单例的bean发现是空 (AnnotationAwareAspecttJAutoProxyCreator的bean名称是org.springframework.aop.config.internalAutoProxyCreator)
3.1.7 创建AnnotationAwareAspecttJAutoProxyCreator 的bean
3.1.8 初始化org.springframework.aop.config.internalAutoProxyCreator
3.1.9 bean类型转换
3.1.10 加入到BeanFactory然后初始化
3.1.11 包装bean初始化
3.1.12 spring二级缓存获取bean
3.1.13 必要时一次性创建bean
3.1.14 创建完毕
4.AbstractAutoProxyCreator.postProcessBeforeInstantiation()方法
postProcessBeforeInstantiation()即实例化之前的后置处理,经过多次调试我们会发现每创建一个bean之前都会经过这里。
经过多次调试分析如下结果:
//AbstractAutoProxyCreator.java
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//为给定的bean类和bean名称构建一个缓存键。
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
//代理bean标记
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
//如果定义了TargetSource 在此处创建代理
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
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;
}
我们看一下getCacheKey()
//为给定的bean类和bean名称构建一个缓存键。
protected Object getCacheKey(Class<?> beanClass, String beanName) {
if (StringUtils.hasLength(beanName)) {
return (FactoryBean.class.isAssignableFrom(beanClass) ?
BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
}
else {
return beanClass;
}
}
如下例子:
返回一个bean名称是demo的对象。
5.AbstractAutoProxyCreator.postProcessAfterInitialization()
//AbstractAutoProxyCreator.java
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
//如果bean被子类标识为代理,则使用配置的拦截器创建代理
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
此方法是bean初始化的时候被调用的。
如下调用栈:
bean初始化
初始化后应用bean处理
我们进入wrapIfNecessary()方法:
/**
* Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && 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.
//子类是否标记代理
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;
}
上述代码大概意思是:如果有bean被子类bean做了代理在这里创建创建bean代理。
调试源码详见地址:
https://github.com/dakele895/...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。