spring aop 是通过动态代理实现的,具体是如何实现的那?spring通过一个切面类,在他类上加入了@Aspect注解,定义一个pointCut方法,最后定义一系列的增强方法。这样就完成了一个对象的切面操作。
基本的思路是
1.找到所有的切面类
2.解析出所有的advice并保存
3.创建一个动态代理类
4.调用被代理类方法时,找到所有的增强器,并增强当前方法
spring通过@EnableAspectJAutoProxy开启aop切面,在注解上面发现@import(AspectAutoProxyRegistrar.class),AspectJAutoProxyRegistrar实现了importBeanDefinitionRegistrar,所以他会通过registerBeanDefinitions方法为我们容器导入beanDefinition
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@import(AspectJAutoProxyRegistrar.class)//为容器中引入AspectJAutoProxyRegistrar
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
//实现了importBeanDefinitionRegistrar
class AspectJAutoProxyRegistrar implements importBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
Annotationmetadata importingClassmetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
}
}
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
最终引入了AnnotationAwareAspectJAutoProxyCreator.class类
解析切面的逻辑在spring 容器创建早起就开始调用了
postProcessBeforeInstantiation是在任意bean创建的时候就调用了 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation
追踪一下源码可以看到最终导入AnnotationAwareAspectJAutoProxyCreator,我们看一下他的类继承关系图,发现它实现了两个重要 的接口,BeanPostProcessor和InstantiationAwareBeanPostProcessor,这两个是bean的后置处理器,在bean的生命周期创建中会执行,首先看InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法 Object postProcessBeforeInstantiation(Class> beanClass, String beanName)(InstantiationAwareBeanPostProcessor) org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
//在spring第一次创建bean的时候,缓存所有的切面 public ListbuildAspectJAdvisors() { //获取缓存中的aspectBeanNames List aspectNames = this.aspectBeanNames; if (aspectNames == null) { synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List advisors = new ArrayList<>(); aspectNames = new ArrayList<>(); //获取beanFactory中所有的beanNames String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); for (String beanName : beanNames) { if (!isEligibleBean(beanName)) { continue; } // We must be careful not to instantiate beans eagerly as in this case they // would be cached by the Spring container but would not have been weaved. Class> beanType = this.beanFactory.getType(beanName, false); if (beanType == null) { continue; } //找出所有类上面含@Aspect注解的bean //提取aspect类中所有的advice方法,将结果缓存advisorsCache if (this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); Aspectmetadata amd = new Aspectmetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { metadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); //1.找到切面类的所有但是不包括@Pointcut注解的方法 33 //2.筛选出来包含@Around, @Before, @After,@ AfterReturning, @AfterThrowing注解的方法 34 //3.封装为List返回 List classAdvisors = this.advisorFactory.getAdvisors(factory); if (this.beanFactory.isSingleton(beanName)) { //将上面找出来的Advisor按照key为beanName,value为List的形式存入advisorsCache,缓存中 this.advisorsCache.put(beanName, classAdvisors); } else { this.aspectFactoryCache.put(beanName, factory); } advisors.addAll(classAdvisors); } else { // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } metadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames = aspectNames; return advisors; } } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } List advisors = new ArrayList<>(); for (String aspectName : aspectNames) { //当再次进入该方法,会直接从advisorsCache缓存中获取 List cachedAdvisors = this.advisorsCache.get(aspectName); if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { metadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; }
其中代码 List classAdvisors = this.advisorFactory.getAdvisors(factory);
public ListgetAdvisors(metadataAwareAspectInstanceFactory aspectInstanceFactory) { Class> aspectClass = aspectInstanceFactory.getAspectmetadata().getAspectClass(); String aspectName = aspectInstanceFactory.getAspectmetadata().getAspectName(); validate(aspectClass); // We need to wrap the metadataAwareAspectInstanceFactory with a decorator // so that it will only instantiate once. metadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List advisors = new ArrayList<>(); for (Method method : getAdvisorMethods(aspectClass)) { Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName); if (advisor != null) { advisors.add(advisor); } } // Find introduction fields. for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; }
getAdvisorMethods
//获取aspectj类下,所有的方法注解方法,除了pointCut private ListgetAdvisorMethods(Class> aspectClass) { final List methods = new ArrayList<>(); ReflectionUtils.doWithMethods(aspectClass, method -> { // Exclude pointcuts if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) { methods.add(method); } }, ReflectionUtils.USER_DECLARED_METHODS); if (methods.size() > 1) { //按照这个进行排序Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class methods.sort(METHOD_COMPARATOR); } return methods; }
这里把切面方法都获取到,放到List中
上面获取容器中所有的bean上带有@Aspect注解bean里的所有标识了@Around,@Before,@After,@AfterReturning,@AfterThrowing等相关的内容,缓存到了集合中,方便后面进行调用。
postProcessAfterInitialization是在bean创建完成之后执行的 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
}
获取advisors
创建代理前首先要判断当前bean是否满足被代理,所以需要将advisor从之前的缓存中拿出来和当前bean根据表达式匹配
Object postProcessAfterInitialization(@Nullable Object bean, String beanName)(BeanPostProcessor) org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors 上述代码的链路最终到了findCandidateAdvisors,我们发现在postProcessBeforeInstantiation方法中对查找到的Advisors做了缓存, 所以这里只需要从缓存中取就好了 最后创建代理类,并将Advisors赋予代理类,缓存当前的代理类
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && 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.
//根据bean找到我们要的advice
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {//如果当前bean的specificInterceptors不为空,说明符合代理条件,需要创建动态代理
this.advisedBeans.put(cacheKey, Boolean.TRUE);//代理的bean放到缓存中
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;
}
protected Object[] getAdvicesAndAdvisorsForBean(
Class> beanClass, String beanName, @Nullable TargetSource targetSource) {
//有资格的advisors
List advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected ListfindEligibleAdvisors(Class> beanClass, String beanName) { List candidateAdvisors = findCandidateAdvisors();//查找所有的advisors //找到当前bean匹配的advisor,如果找到了说明满足创建动态代理的条件 //查找的过程总分粗筛选,精筛,利用aspectj的切点表达式解析匹配能力 List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors);//排序动态advisors代理 } return eligibleAdvisors; }
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Advisor, java.lang.Class>, boolean) 拿到PointCut org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class>, boolean) org.springframework.aop.ClassFilter#matches 粗筛 org.springframework.aop.IntroductionAwareMethodMatcher#matches 精筛
创建代理找到了和当前bean匹配的advisor说明满足创建动态代理条件:
AbstractAutoProxyCreator.wrapIfNecessary.createProxy
Object proxy = createProxy(//执行实际的创建 bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
protected Object createProxy(Class> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
return proxyFactory.getProxy(getProxyClassLoader());
}
proxyFactory.getProxy(getProxyClassLoader())
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
创建代理
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)) {
//jdk动态代理,如果是类
return new JdkDynamicAopProxy(config);
}
//cglib动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
如果有接口使用jdk动态代理,如果没有接口使用cglig动态代理;
调用前面分析可知,spring将找到的增强器advisors赋予了代理类,那么在执行时只要将这些增强器应用到被代理的类上面就可以了,那么spring具体怎么实现的那,以jdk代理为例:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource; //目标类
Object target = null;
try {// equals,hashcode等方法不做代理,直接调用
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
Object retVal;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
Class> targetClass = (target != null ? target.getClass() : null);
// 将增强器转换为方法执行拦截器链条
// Get the interception chain for this method.
List
其中,this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,targetClass);
将增强器转为了方法执行的拦截器链条,通过上面代码可知,将增强器装换为方法拦截器链,最终包装为ReflectiveMethodInvocation执行它的proceed方法
我们看下
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//从-1开始,结束条件:执行目标方法是下标=拦截器-1(执行到了最后一个拦截器的时候)
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//通过反射的方式执行目标类的目标方法,最后才会调用
return invokeJoinpoint();
}
//获取集合当前需要运行的拦截器,每次递归回来加一个,获取下一个拦截器
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);//currentInterceptorIndex 成员变量,每次加1
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed. //每一次把自己传入进去,通过++调用不同的链路
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
这样一看会感觉很蒙,其实追踪一下源码就很好理解了
org.springframework.aop.interceptor.ExposeInvocationInterceptor#invoke
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
上面代码传的是((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
this代表了当前对象,所以mi.proceed()又回调回去了
org.springframework.aop.aspectj.AspectJAfterThrowingAdvice#invoke
异常拦截器,当前方法异常会执行
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {//只有异常才会执行
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor#invoke
返回拦截器,方法执行失败,不会执行
@Override
public Object invoke(MethodInvocation mi) throws Throwable {//返回变量
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
org.springframework.aop.aspectj.AspectJAfterAdvice#invoke
后置拦截器,总是执行,异常也执行
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {//先调用下面的链路,再调用finally方法,保证有异常也会调用后置处理器
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor#invoke
前置拦截器
@Override
public Object invoke(MethodInvocation mi) throws Throwable {//前置接口
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
这里用了责任链的设计模式,递归调用排序好的拦截器链
当调用完成责任链后
执行目标方法 invokeJoinpoint()
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();//通过反射的方式执行目标类的目标方法
}
完成任务



