NND ,源码实在复杂,先整理个思路吧
AOP配置文件demo
<bean id="daoImpl" class="com.xx.xx.pcwebv2.Dao.CDaoImp" />
<bean id="timeHandler" class="com.xx.xx.pcwebv2.Dao.TimeHandler" />
<aop:config proxy-target-class="true">
<aop:aspect id="time" ref="timeHandler">
<aop:pointcut id="addAllMethod" expression="execution(* com.xx.xx.pcwebv2.Dao.IDaoTest.select(..))" />
<aop:before method="printTime" pointcut-ref="addAllMethod" />
<aop:after method="printTime" pointcut-ref="addAllMethod" />
</aop:aspect>
</aop:config>
核心类是:AspectJAwareAdvisorAutoProxyCreator
, 在解析XML文件时, 以上配置在IOC中会额外多出如下beanDefinition
在每个Bean构造之后,调用方法initializeBean
,对Bean进行包装,
包装思路如下:
判断Bean是否符合pointcut 表达式的条件,符合时,对该原始bean生成代理, 原始Bean的方法调用时,激活代理方法, 分别执行被包装过的代理对象相应的通知方法.
1.找到所有Advisor ,
然后判断当前Class是否满足pointcut的expression
匹配规则,
1. 取当前bean及所有父类的方法,组成class数组
2. 遍历class数组中每个类的方法, 根据pointcunt的表达式进行匹配
3.遍历成功后对此Bean进行代理,接口使用JDK动态代理,方法使用CGlib代理
2. 代理调用方式:
this.interceptorsAndDynamicMethodMatchers 保存有adviser列表, 逐个执行.
所有before结束后执行 被代理的真实的方法
执行AspectJAfterAdvice 方法
主要源码如下;
每一个Bean构建后都会调用方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
:
在此方法中调用BeanPostProcessor
的实现类,
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//前置通知
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
if (mbd == null || !mbd.isSynthetic()) {
//后置通知.
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
在初始化”org.springframework.aop.aspectj.AspectJPointcutAdvisor#0” 时, 调用方法
AbstractAutoProxyCreator.postProcessAfterInitialization
,源码如下:
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//1.
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
1处为核心代码, 判断是否需要对此Bean生成代理, 源码如下:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//2.
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;
}
//getAdvicesAndAdvisorsForBean 会调用如下方法
//org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
//用来获取跟当前Bean匹配所有Advisors
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;
}
当findEligibleAdvisors返回结果大于零时, 标示此Bean符合被拦截的条件, 则Bean被动态代理,执行2处代码.
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
原始Bean对象被替换成代理对象返回
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
// ......
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
//原始Bean对象被替换成代理对象返回
return wrappedBean;
}
//
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Initialize the bean instance.
Object exposedObject = bean;
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//Bean已经被替换为代理对象.
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
return exposedObject;
}