@EnableAspectJAutoProxy
这个注解是spring启用在自己的容器中注册了一个组件
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProx
AspectJAutoProxyRegistrar就是在spring注册了这个类,这个类实现了ImportBeanDefinitionRegistrar
重写registerBeanDefinitions方法,
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
即注册了个应该beanName为org.springframework.aop.config.internalAutoProxyCreator 对象值为AnnotationAwareAspectJAutoProxyCreator的
AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
SmartInstantiationAwareBeanPostProcessor又实现InstantiationAwareBeanPostProcessor接口。
实现了InstantiationAwareBeanPostProcessor后置处理的接口 会再容器初始化完成bean以后执行器 后置处理器的before和after方法,BeanFactoryAware表示 其子类是可以拿到spring的 BeanFactory的,也就是所有bean的对象,不然你aspectj中怎么执行,被增强对象的 增强方法,因为增强的方法属于spring管理的对象的方法。(不是只接new 对象调用的方法)
spring的源码片段
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])
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(String, RootBeanDefinition)
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//创建bean之前执行实现了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
if (bean != null) {
//执行实现了后置处理的after方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
那我们再看下 这个postProcessBeforeInstantiation都干啥了
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(Class<?>, String)
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
//targetSourcedBeans就是一个集合,advisedBeans标识通知的集合,nonAdvisedBeans标识不同的对象
if (!this.targetSourcedBeans.contains(cacheKey)) {
if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) {
return null;
}
//Advisor,Advice,AopInfrastructureBean判断父类是不是这三个类 || 含有这个Aspect注解
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.nonAdvisedBeans.add(cacheKey);
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 = 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;
}
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(Object, String)
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的方法是否需要被切
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (this.nonAdvisedBeans.contains(cacheKey)) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.nonAdvisedBeans.add(cacheKey);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {//说明这个bean需要被切
this.advisedBeans.add(cacheKey);
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));//创建代理对象
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.nonAdvisedBeans.add(cacheKey);
return bean;
}
上面的getAdvicesAndAdvisorsForBean方法跟进去会调用这个方法
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(Class, String)
protected List<Advisor> findEligibleAdvisors(Class beanClass, String beanName) {
//遍历所有beanFactory中的bean查找到所有的切面,并且找到类中所有的通知方法。也就是候选的通知
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//遍历所以所有的候选通知,看那些是能适用到当前bean中的。
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
到这里 ,代理对象就已经创建完毕了,spring管理的是我们创建的代理对象。
当我们使用代理执行目标方法的时候,如果使用的是cglib的话,会被invoke方法拦截
org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy)
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class<?> targetClass = null;
Object target = null;
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool...
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
//获取这个对象目标方法所有适配的通知方法。
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); //--》》////getInterceptorsAndDynamicInterceptionAdvice()---》getInterceptorsAndDynamicInterceptionAdvice
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
//调用目标方法,并且会从spring容器中寻找通知方法类所对应的对象,同时调用通知方法。
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}