spring aop源码解析2: AnnotationAwareAspectJAutoProxyCreator拦截切点bean(join point)创建过程并生成proxy(在切点织入切面)的过程
接上一篇spring aop源码解析1: 创建、初始化并注册AnnotationAwareAspectJAutoProxyCreator继续
现在我们在容器中已经有了AnnotationAwareAspectJAutoProxyCreator这个BeanPostProcessor,那么之后我们再创建bean的时候,都会经过AnnotationAwareAspectJAutoProxyCreator这个后置处理器
接下来看这个后置处理器能干什么
AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor
由于流程比较复杂,还是先上一张流程图
4.完成其余BeanFactory的初始化工作
在refresh方法中 注册好了BeanPostProcessor之后,执行finishBeanFactoryInitialization方法
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
初始化剩下的单实例bean
为什么说是剩下的bean呢?比如说我们的一些BeanPostProcessor bean,已经在前面创建、初始化并注册到容器中了
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
这里的beanFactory是DefaultListenableBeanFactory
4.1 遍历获取容器中所有的Bean,依次创建对象getBean(beanName);
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
...
else {
getBean(beanName);
}
getBean->doGetBean()->getSingleton()->
4.2 创建bean
AnnotationAwareAspectJAutoProxyCreator这个BeanPostProcessor会在所有bean创建之前会有一个拦截,因为其实现了InstantiationAwareBeanPostProcessor,会调用postProcessBeforeInstantiation()
4.2.1 先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
只要创建好的Bean都会被缓存起来,保证单实例Bean只会被创建一次
4.2.2 createBean();创建bean;
Central method of this class: creates a bean instance,populates the bean instance, applies post-processors, etc.
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
AnnotationAwareAspectJAutoProxyCreator 会在任何bean创建之前先尝试返回bean的实例
BeanPostProcessor后置处理器与InstantiationAwareBeanPostProcessor后置处理器不一样
BeanPostProcessor是在Bean对象创建完成初始化前后调用的
InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象的
4.2.2.1 resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation
希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用,如果不能就继续执行doCreateBean
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
后置处理器先尝试返回对象;
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
先执行applyBeanPostProcessorsBeforeInstantiation
如果不为null,再执行applyBeanPostProcessorsAfterInitialization
拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor这种类型
注意,我们第3步创建的AnnotationAwareAspectJAutoProxyCreator就是这种类型的BeanPostProcessor
就执行postProcessBeforeInstantiation
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation
注意看注解:
如果我们有自定义TargetSource,请在此处创建代理。
禁止目标bean的不必要的默认实例化:
TargetSource将以自定义方式处理目标实例。
也就是说当注册了AnnotationAwareAspectJAutoProxyCreator之后,再创建任何一个bean的时候,都要先被其拦截一下,看这个bean是直接由这个BeanPostProcessor生成一个proxy对象后返回,还是走常规的创建过程
4.2.2.2 如果不能,
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
真正的去创建一个bean实例;和3.4创建AnnotationAwareAspectJAutoProxyCreator这个bean流程一样;
5. AnnotationAwareAspectJAutoProxyCreator拦截切点bean(join point)创建过程并生成proxy(在切点织入切面)的过程
AnnotationAwareAspectJAutoProxyCreator
其实现了InstantiationAwareBeanPostProcessor
其处理过程
5.1. 每一个bean创建之前,调用postProcessBeforeInstantiation();
关心MathCalculator和LogAspect的创建
5.1.1 判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
5.1.2 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
先执行
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass
return (super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass));
注意在这里判断了是不是@Aspect
调用AnnotationUtils类来判断
org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#hasAspectAnnotation
private boolean hasAspectAnnotation(Class<?> clazz) {
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}
之后再执行
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#isInfrastructureClass
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
在这里判断是不是Advice、Pointcut、Advisor、AopInfrastructureBean类型
5.1.3 判断是否需要跳过
org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor) {
if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
return true;
}
}
}
return super.shouldSkip(beanClass, beanName);
}
5.1.3.1 获取候选的增强器(切面里面的Advice方法)
List<Advisor> candidateAdvisors
每一个封装的通知方法的增强器类型是InstantiationModelAwarePointcutAdvisor;
判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;
由于我们的增强器类型是InstantiationModelAwarePointcutAdvisor,不是AspectJPointcutAdvisor 类型的
5.1.3.2 永远返回false
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip
永远返回false
实际上我们的@Aspect切面类会加入到advisedBeans中
this.advisedBeans.put(cacheKey, Boolean.FALSE);
5.2. 创建对象
调用完postProcessBeforeInstantiation之后,
就要创建对象了
@Bean
public MathCalculator calculator(){
return new MathCalculator();
}
这个calcalator对象是要创建为代理对象的,要把切面织入进来
//切面类加入到容器中
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
之后调用
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
这个方法的作用:如果bean被标识为(切点表达式)一个代理,那么就使用已配置的拦截器创建代理对象
@Override
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;
}
postProcessAfterInitialization;
return wrapIfNecessary(bean, beanName, cacheKey);
//如果需要的情况下包装
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
// 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;
在这里就创建proxy了
5.2.1 获取当前bean的所有增强器(通知方法)
Object[] specificInterceptors
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
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;
}
5.2.1.1 找到候选的所有的增强器(找哪些Advice方法是能够切入(切点)当前bean方法的)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
5.2.1.2 获取到能在bean使用的增强器。
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
5.2.1.3 给增强器排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
5.2.2 保存当前bean在advisedBeans中;
this.advisedBeans.put(cacheKey, Boolean.TRUE);
5.2.3 如果当前bean需要增强,创建当前bean的代理对象;
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
5.2.3.1 获取所有增强器(Advice方法)
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
5.2.3.2 保存到proxyFactory
proxyFactory.addAdvisors(advisors);
5.2.3.3 创建代理对象:Spring自动决定
return proxyFactory.getProxy(getProxyClassLoader());
JdkDynamicAopProxy(config);jdk动态代理;
ObjenesisCglibAopProxy(config);cglib的动态代理;
org.springframework.aop.framework.DefaultAopProxyFactory
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
可以看到,targetClass是
5.2.3.4 给容器中返回当前组件使用cglib增强了的代理对象;
我们的calculator未实现接口,所以创建一个cglib增强了的代理对象
返回的就是一个增强了的代理对象
5.2.3.5 以后容器中获取到的就是这个组件的代理对象
执行目标方法的时候,代理对象就会执行增强方法的流程