1.Spring AOP的加载过程
生命周期:
1.postProcessBeforeInstantiation
2.解析注解@Aspect标识的类
3.postProcessAfterInitialization
4.找出匹配当前bean的Advisor
5.对Advisor进行排序
6.创建代理对象
7.调用代理对象
8.获取拦截器链
9.将advisor转换成MethodInterceptor
10.执行拦截器链
理解是:
1.扫描所有标注了@Aspect的类。放入一个cache中,并且对所有的Advisor里面的方法进行排序。
2.postProcessBeforeInstantiation判断当前类是否与切面的逻辑有关,即是否需要增强。
3.postProcessAfterInitialization 生成代理对象。
4.找到Advisor,调用等环节
通过 @Aspect 注解配置切面,通过 @EnableAspectJAutoProxy 注解开启AOP配置,引入
AspectJAutoProxyRegistrar类,最终会注册一个AnnotationAwareAspectJAutoProxyCreator类
因为AnnotationAwareAspectJAutoProxyCreator继承自BeanPostProcessor
postProcessBeforeInstantiation
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 判断当前bean是否与切面逻辑有关(Adivsor,Adivce,Pointcut实现类)
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
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, 如果存在则直接在对象初始化之前进行创建代理, 避免了目标对象不必要的实例化
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
//如果有自定义targetSource就要这里创建代理对象
//这样做的好处是被代理的对象可以动态改变,而不是只针对一个target对象(可以对对象池中对象进行代理,可以每次创建代理都创建新对象)
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
//获取Advisors, 这个是交给子类实现的
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
//获取切面
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
//找到所有可用的切面,并且对切面进行排序
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
解析注解@Aspect标识的类
postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
//返回bean的名字或class
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
/**
* 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.
// 1.查找出和当前bean匹配的advisor
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的Advisor
创建代理对象
调用代理对象
获取拦截器链
将postProcessAfterInitialization排序完,可适配当前切点的Advisor 形成拦截器链进行调用?
将Advisor 转成MethodInterceptor