/**
* cglib动态代理实现逻辑
*/@Overridepublic Object getProxy(@Nullable ClassLoader classLoader){if(logger.isTraceEnabled()){
logger.trace("Creating CGLIB proxy: "+this.advised.getTargetSource());}try{// 被代理的类
Class<?> rootClass =this.advised.getTargetClass();
Assert.state(rootClass != null,"Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;// 如果被代理类本身就已经是Cglib所生成的代理类了if(rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)){// 获取真正的被代理类
proxySuperClass = rootClass.getSuperclass();// 获取被代理类所实现的接口
Class<?>[] additionalInterfaces = rootClass.getInterfaces();for(Class<?> additionalInterface : additionalInterfaces){this.advised.addInterface(additionalInterface);}}// Validate the class, writing log messages as necessary.validateClassIfNecessary(proxySuperClass, classLoader);// Configure CGLIB Enhancer...
Enhancer enhancer =createEnhancer();if(classLoader != null){
enhancer.setClassLoader(classLoader);if(classLoader instanceofSmartClassLoader&&((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)){
enhancer.setUseCache(false);}}// 被代理类,代理类的父类。可以进行强转
enhancer.setSuperclass(proxySuperClass);// 代理类额外要实现的接口。可以进行强转enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(newClassLoaderAwareGeneratorStrategy(classLoader));// 获取和被代理类所匹配的Advisor
Callback[] callbacks =getCallbacks(rootClass);
Class<?>[] types =newClass<?>[callbacks.length];for(int x =0; x < types.length; x++){
types[x]= callbacks[x].getClass();}// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(newProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(),this.fixedInterceptorMap,this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);// Generate the proxy class and create a proxy instance.returncreateProxyClassAndInstance(enhancer, callbacks);}catch(CodeGenerationException| IllegalArgumentException ex){thrownewAopConfigException("Could not generate CGLIB subclass of "+this.advised.getTargetClass()+": Common causes of this problem include using a final class or a non-visible class",
ex);}catch(Throwable ex){// TargetSource.getTarget() failedthrownewAopConfigException("Unexpected AOP exception", ex);}}
JDK动态代理的实现逻辑
/**
* JDK动态代理实现逻辑
*/@Overridepublic Object getProxy(@Nullable ClassLoader classLoader){if(logger.isTraceEnabled()){
logger.trace("Creating JDK dynamic proxy: "+this.advised.getTargetSource());}// this实现了InvocationHandlerreturn Proxy.newProxyInstance(classLoader,this.proxiedInterfaces,this);}/**
* 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()方法直接执行。如果接口中没有定义equals()方法,那么则直接调用,不走代理if(!this.equalsDefined && AopUtils.isEqualsMethod(method)){// The target does not implement the equals(Object) method itself.returnequals(args[0]);}// HashCode()方法直接执行。如果接口中没有定义HashCode()方法,那么则直接调用,不走代理elseif(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)){// The target does not implement the hashCode() method itself.returnhashCode();}elseif(method.getDeclaringClass()== DecoratingProxy.class){// There is only getDecoratedClass() declared -> dispatch to proxy config.// 得到代理对象的类型,而不是所实现的接口return AopProxyUtils.ultimateTargetClass(this.advised);}elseif(!this.advised.opaque && method.getDeclaringClass().isInterface()&&
method.getDeclaringClass().isAssignableFrom(Advised.class)){// Service invocations on ProxyConfig with the proxy config...// 也是直接调用Advised接口中的方法,不走代理逻辑// 其实就是利用代理对象获取ProxyFactory中的信息return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);}
Object retVal;// 如果ProxyFactory的exposeProxy为true,则将代理对象设置到currentProxy这个ThreadLocal中去。// 可以通过AopContext.currentProxy()来获取当前的代理对象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.// 调用getTarget得到被代理对象
target = targetSource.getTarget();// 得到代理类
Class<?> targetClass =(target != null ? target.getClass(): null);// Get the interception chain for this method.// 代理对象在执行某个方法时,根据方法筛选出匹配的Advisor,并适配成Interceptor// this.advised是ProxyFactory对象
List<Object> chain =this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);// Check whether we have any advice. If we don't, we can fallback on direct// reflective invocation of the target, and avoid creating a MethodInvocation.// chain是空的说明没有代理逻辑if(chain.isEmpty()){// 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.// 如果没有Advice,则直接调用对应方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);}else{// We need to create a method invocation...
MethodInvocation invocation =newReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();}// Massage return value if necessary.
Class<?> returnType = method.getReturnType();if(retVal != null && retVal == target &&
returnType != Object.class&& returnType.isInstance(proxy)&&!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())){// Special case: it returned "this" and the return type of the method// is type-compatible. Note that we can't help if the target sets// a reference to itself in another returned object.
retVal = proxy;}elseif(retVal == null && returnType != Void.TYPE && returnType.isPrimitive()){thrownewAopInvocationException("Null return value from advice does not match primitive return type for: "+ method);}return retVal;}finally{if(target != null &&!targetSource.isStatic()){// Must have come from TargetSource.
targetSource.releaseTarget(target);}if(setProxyContext){// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);}}}/**
* 无代理逻辑,直接执行被代理的方法
*/publicstatic Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)throws Throwable {// Use reflection to invoke the method.try{
ReflectionUtils.makeAccessible(method);// 执行普通对象的方法,注意和@Configuration产生的代理对象的逻辑区别return method.invoke(target, args);}catch(InvocationTargetException ex){// Invoked method threw a checked exception.// We must rethrow it. The client won't see the interceptor.throw ex.getTargetException();}catch(IllegalArgumentException ex){thrownewAopInvocationException("AOP configuration seems to be invalid: tried calling method ["+
method +"] on target ["+ target +"]", ex);}catch(IllegalAccessException ex){thrownewAopInvocationException("Could not access method ["+ method +"]", ex);}}/**
* 代理对象在执行某个方法时,根据方法筛选出匹配的Advisor,并适配成Interceptor
* method:被代理方法
* targetClass:被代理类
*/public List<Object>getInterceptorsAndDynamicInterceptionAdvice(Method method,@Nullable Class<?> targetClass){// 代理对象在执行某个方法时,会根据当前ProxyFactory中所设置的Advisor根据当前Method再次进行过滤
MethodCacheKey cacheKey =newMethodCacheKey(method);// 注意这个List,表示的就是Advice链。从缓冲中获取。
List<Object> cached =this.methodCache.get(cacheKey);if(cached == null){// 缓冲没有的时候,进行查找
cached =this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);this.methodCache.put(cacheKey, cached);}return cached;}/**
* 缓冲中没有的情况下,构建Interceptors
* config:ProxyFactory对象
* method:被代理方法
* targetClass:被代理类
*/public List<Object>getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method,@Nullable Class<?> targetClass){// This is somewhat tricky... We have to process introductions first,// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();// 从ProxyFactory中拿到所设置的Advice(添加时被封装成了DefaultPointcutAdvisor)// 添加的时候会控制顺序。ProxyFactory.addAdvice的时候会添加。
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList =newArrayList<>(advisors.length);
Class<?> actualClass =(targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;// 遍历每一个Advisorfor(Advisor advisor : advisors){// PointcutAdvisor类型的处理if(advisor instanceofPointcutAdvisor){// Add it conditionally.
PointcutAdvisor pointcutAdvisor =(PointcutAdvisor) advisor;// 先匹配被代理的类是否符合getClassFilter的逻辑(一个Pointcut有俩个方法,一个是匹配类的,一个是匹配方法的)if(config.isPreFiltered()|| pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)){// 再匹配方法是否符合getMethodMatcher的逻辑
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();boolean match;if(mm instanceofIntroductionAwareMethodMatcher){if(hasIntroductions == null){
hasIntroductions =hasMatchingIntroductions(advisors, actualClass);}
match =((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);}else{
match = mm.matches(method, actualClass);}// 方法匹配到了if(match){// 如果匹配则将Advisor封装成为Interceptor,当前Advisor中的Advice可能即是MethodBeforeAdvice,也是ThrowsAdvice。
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);// 方法匹配器的自定义方法isRuntime()返回true。if(mm.isRuntime()){// Creating a new object instance in the getInterceptors() method// isn't a problem as we normally cache created chains.// isRuntime()返回true的时候,后面会进行参数的校验for(MethodInterceptor interceptor : interceptors){
interceptorList.add(newInterceptorAndDynamicMethodMatcher(interceptor, mm));}}else{
interceptorList.addAll(Arrays.asList(interceptors));}}// 最终,interceptorList中存储的是当前正在执行的Method所匹配的MethodInterceptor,可能动态的,也可能是非动态的,// 找到Method所匹配的MethodInterceptor后,就会开始调用这些MethodInterceptor,如果是动态的,会额外进行方法参数的匹配}}// Introduction,指定接口的逻辑elseif(advisor instanceofIntroductionAdvisor){
IntroductionAdvisor ia =(IntroductionAdvisor) advisor;if(config.isPreFiltered()|| ia.getClassFilter().matches(actualClass)){
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));}}else{// 将Advisor封装成为Interceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));}}return interceptorList;}
public Object proceed()throws Throwable {// We start with an index of -1 and increment early.// currentInterceptorIndex初始值为-1,每调用一个interceptor就会加1// 当调用完了最后一个interceptor后就会执行被代理方法if(this.currentInterceptorIndex ==this.interceptorsAndDynamicMethodMatchers.size()-1){returninvokeJoinpoint();}// currentInterceptorIndex初始值为-1
Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);// 当前interceptor是InterceptorAndDynamicMethodMatcher,则先进行匹配,匹配成功后再调用该interceptor// 如果没有匹配则递归调用proceed()方法,调用下一个interceptorif(interceptorOrInterceptionAdvice instanceofInterceptorAndDynamicMethodMatcher){// 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.// 不匹配则执行下一个MethodInterceptorreturnproceed();}}else{// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.// 直接调用MethodInterceptor,传入this,在内部会再次调用proceed()方法进行递归// 比如MethodBeforeAdviceInterceptorreturn((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}
AOP是如何使用动态代理的
/**
* 开启AOP的注解导入了AspectJAutoProxyRegistrar类
*/@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(AspectJAutoProxyRegistrar.class)public @interfaceEnableAspectJAutoProxy{booleanproxyTargetClass()defaultfalse;booleanexposeProxy()defaultfalse;}/**
* 被导入的类他是一个ImportBeanDefinitionRegistrar
*/classAspectJAutoProxyRegistrarimplementsImportBeanDefinitionRegistrar{@OverridepublicvoidregisterBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry){// 注册一个AnnotationAwareAspectJAutoProxyCreator类型的Bean,beanName为AUTO_PROXY_CREATOR_BEAN_NAME
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);// 修改AnnotationAwareAspectJAutoProxyCreator中对应的属性
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);if(enableAspectJAutoProxy != null){// 给proxyTargetClass默认值为true:默认使用cglib动态代理if(enableAspectJAutoProxy.getBoolean("proxyTargetClass")){
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);}// 给exposeProxy默认值为true:默认放入threadLocal中if(enableAspectJAutoProxy.getBoolean("exposeProxy")){
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);}}}}/**
* 被导入的注册了一个AnnotationAwareAspectJAutoProxyCreator类型的Bean
* 他是一个BeanPostProcessor,会在创建Bean的时候调用。
*/publicclassAnnotationAwareAspectJAutoProxyCreatorextendsAspectJAwareAdvisorAutoProxyCreator{}/**
* 在初始化的时候会执行postProcessAfterInitialization方法
* 会调用到AbstractAutoProxyCreator的postProcessAfterInitialization
*/@Overridepublic Object postProcessAfterInitialization(@Nullable Object bean, String beanName){if(bean != null){
Object cacheKey =getCacheKey(bean.getClass(), beanName);if(this.earlyProxyReferences.remove(cacheKey)!= bean){// 调用这个包装的方法returnwrapIfNecessary(bean, beanName, cacheKey);}}return bean;}/**
* 初始化后会进入这个方法
*/protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey){// beanName存在长度并且没有进行缓存(目前没找到他缓存放入的位置)if(StringUtils.hasLength(beanName)&&this.targetSourcedBeans.contains(beanName)){return bean;}// advisedBeans表示已经判断过了的bean,false表示此bean不需要进行Aopif(Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))){return bean;}// 当前正在创建的Bean不用进行AOP,比如切面Bean// 前面判断的固定的,后面的判断库进行扩展if(isInfrastructureClass(bean.getClass())||shouldSkip(bean.getClass(), beanName)){// 不需要进行AOP的标记放入缓存,下次进来第二个判断直接返回this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}// Create proxy if we have advice.// 判断当前bean是否存在匹配的advice,如果存在则要生成一个代理对象// 此处根据类以及类中的方法去匹配到Interceptor(也就是Advice),然后生成代理对象,代理对象在执行的时候,还会根据当前执行的方法去匹配
Object[] specificInterceptors =getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);if(specificInterceptors != DO_NOT_PROXY){// advisedBeans记录了某个Bean已经进行过AOP了this.advisedBeans.put(cacheKey, Boolean.TRUE);// 创建代理对象
Object proxy =createProxy(
bean.getClass(), beanName, specificInterceptors,newSingletonTargetSource(bean));// 代理对象类型的缓存this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}/**
* 判断哪些类不需要进行AOP
*/protectedbooleanisInfrastructureClass(Class<?> beanClass){// AOP相关的类,不需要进行AOPboolean 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;}/**
* 根据Bean信息找到Advices
*/protected Object[]getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName,@Nullable TargetSource targetSource){// 寻找匹配的Advisor
List<Advisor> advisors =findEligibleAdvisors(beanClass, beanName);// 为空返回nullif(advisors.isEmpty()){return DO_NOT_PROXY;}return advisors.toArray();}/**
* 根据Bean信息找到符合的条件的Advices
*/protected List<Advisor>findEligibleAdvisors(Class<?> beanClass, String beanName){// 找到所有的Advisor
List<Advisor> candidateAdvisors =findCandidateAdvisors();// 进行筛选。Ian匹配类,后匹配方法
List<Advisor> eligibleAdvisors =findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);extendAdvisors(eligibleAdvisors);// 对Advisor进行排序,按Ordered接口、@Order注解进行排序if(!eligibleAdvisors.isEmpty()){
eligibleAdvisors =sortAdvisors(eligibleAdvisors);}return eligibleAdvisors;}/**
* 找到所有的Advisor
*/protected List<Advisor>findCandidateAdvisors(){// Add all the Spring advisors found according to superclass rules.// 先找到所有Advisor类型的Bean对象。找到所有类型是Advisor的Bean。
List<Advisor> advisors =super.findCandidateAdvisors();// Build Advisors for all AspectJ aspects in the bean factory.// 再从所有切面中解析得到Advisor对象。这里会解析@Aspect相关的注解的类。if(this.aspectJAdvisorsBuilder != null){
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());}return advisors;}/**
* 创建代理对象
*/protected Object createProxy(Class<?> beanClass,@Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource){if(this.beanFactory instanceofConfigurableListableBeanFactory){
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);}
ProxyFactory proxyFactory =newProxyFactory();
proxyFactory.copyFrom(this);if(proxyFactory.isProxyTargetClass()){// Explicit handling of JDK proxy targets (for introduction advice scenarios)if(Proxy.isProxyClass(beanClass)){// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.for(Class<?> ifc : beanClass.getInterfaces()){
proxyFactory.addInterface(ifc);}}}else{// No proxyTargetClass flag enforced, let's apply our default checks...if(shouldProxyTargetClass(beanClass, beanName)){
proxyFactory.setProxyTargetClass(true);}else{evaluateProxyInterfaces(beanClass, proxyFactory);}}
Advisor[] advisors =buildAdvisors(beanName, specificInterceptors);// 在这一步会去判断advisors中是否存在IntroductionAdvisor,如果存在则会把对应的interface添加到proxyFactory中去
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);if(advisorsPreFiltered()){
proxyFactory.setPreFiltered(true);}// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader =getProxyClassLoader();if(classLoader instanceofSmartClassLoader&& classLoader != beanClass.getClassLoader()){
classLoader =((SmartClassLoader) classLoader).getOriginalClassLoader();}// AOP最核心的代码,创建代理对象!return proxyFactory.getProxy(classLoader);}
@Aspect注解的相关解析
/*
* 本方法会被多次调用,因为一个Bean在判断要不要进行AOP时,都会调用这个方法.
*/public List<Advisor>buildAspectJAdvisors(){// aspectBeanNames是用来缓存BeanFactory中所存在的切面beanName的,第一次为null,后面就不为null了,不为null表示之前就已经找到过BeanFactory中的切面了
List<String> aspectNames =this.aspectBeanNames;if(aspectNames == null){synchronized(this){
aspectNames =this.aspectBeanNames;if(aspectNames == null){
List<Advisor> advisors =newArrayList<>();
aspectNames =newArrayList<>();// 把所有beanNames拿出来遍历,判断某个bean的类型是否是Aspect
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class,true,false);// 遍历所有的BeanNamefor(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.// 得到当前Bean的class对象
Class<?> beanType =this.beanFactory.getType(beanName,false);if(beanType == null){continue;}// 存在@Aspect注解的时候会进入当前判断if(this.advisorFactory.isAspect(beanType)){// 标记为他有@Aspect注解
aspectNames.add(beanName);// 切面的注解信息
AspectMetadata amd =newAspectMetadata(beanType, beanName);// 如果@Aspect不是perthis、pertarget,那么一个切面只会生成一个对象(单例)// 并且会将该切面中所对应的Advisor对象进行缓存if(amd.getAjType().getPerClause().getKind()== PerClauseKind.SINGLETON){
MetadataAwareAspectInstanceFactory factory =newBeanFactoryAspectInstanceFactory(this.beanFactory, beanName);// 利用BeanFactoryAspectInstanceFactory来解析Aspect类
List<Advisor> classAdvisors =this.advisorFactory.getAdvisors(factory);// 单例缓存Advisor,不是单例缓存Aspect工厂if(this.beanFactory.isSingleton(beanName)){// 缓存切面所对应的所有Advisor对象this.advisorsCache.put(beanName, classAdvisors);}else{this.aspectFactoryCache.put(beanName, factory);}// 把advisor存入集合
advisors.addAll(classAdvisors);}else{// Per target or per this.// 单例Bean,但是aspect不是单例的,抛异常if(this.beanFactory.isSingleton(beanName)){thrownewIllegalArgumentException("Bean with name '"+ beanName +"' is a singleton, but aspect instantiation model is not singleton");}
MetadataAwareAspectInstanceFactory factory =newPrototypeAspectInstanceFactory(this.beanFactory, beanName);this.aspectFactoryCache.put(beanName, factory);// 利用PrototypeAspectInstanceFactory来解析Aspect类// PrototypeAspectInstanceFactory的父类为BeanFactoryAspectInstanceFactory// 这两个Factory的区别在于PrototypeAspectInstanceFactory的构造方法中会判断切面Bean是不是原型,除此之外没有其他区别// 所以主要就是BeanFactoryAspectInstanceFactory来负责生成切面实例对象
advisors.addAll(this.advisorFactory.getAdvisors(factory));}}}this.aspectBeanNames = aspectNames;// 循环完成,返回advisorreturn advisors;}}}// 空长度的aspectNames,返回空长度的数组if(aspectNames.isEmpty()){return Collections.emptyList();}// 如果切面已经找到过了,那么则遍历每个切面是否缓存了对应的Advisor,如果没有缓存则进行解析得到Advisor
List<Advisor> advisors =newArrayList<>();for(String aspectName : aspectNames){
List<Advisor> 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;}/*
* 拿到所有的Advisor方法,没有加@Pointcut的方法
*/private List<Method>getAdvisorMethods(Class<?> aspectClass){
List<Method> methods =newArrayList<>();// 拿到切面类中所有没有加@Pointcut的方法
ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);// 对方法进行排序,按注解和方法名字进行排序if(methods.size()>1){
methods.sort(adviceMethodComparator);}return methods;}/*
* 切面的排序逻辑
*/static{// 简单理解先后顺序为:@Around, @Before, @After, @AfterReturning, @AfterThrowing
Comparator<Method> adviceKindComparator =newConvertingComparator<>(newInstanceComparator<>(
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),(Converter<Method, Annotation>) method ->{
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);return(ann != null ? ann.getAnnotation(): null);});// 存在多个相同的,比如多个@Before,会按照方法的名字进行排序(字母排序)。
Comparator<Method> methodNameComparator =newConvertingComparator<>(Method::getName);
adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);}/*
* 得到所有的Advisor
*/public List<Advisor>getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory){// 得到aspect的类信息
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();// 得到aspect的名称
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();validate(aspectClass);// 保证切面Bean对象只会实例化一次// 一定要注意,这里是直接new出来一个LazySingletonAspectInstanceFactoryDecorator// 也就是BService这个Bean在执行Bean生命周期过程中,会需要判断要不要进行AOP,就会找到切面,// 发现切面如果是pertarget或perthis,那么就会进入到这个方法,就会new一个LazySingletonAspectInstanceFactoryDecorator// 对于AService也是一样的,在它的Bean的生命周期过程中,也会进入到这个方法,也会new一个LazySingletonAspectInstanceFactoryDecorator
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =newLazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors =newArrayList<>();// 获取切面类中没有加@Pointcut的方法,进行遍历生成Advisorfor(Method method :getAdvisorMethods(aspectClass)){// 得到(解析)为Advisor
Advisor advisor =getAdvisor(method, lazySingletonAspectInstanceFactory,0, aspectName);// 解析出来存起来if(advisor != null){
advisors.add(advisor);}}// @Aspect("pertarget(this(com.zhangwei.service.UserService))")// @Aspect("perthis(this(com.zhangwei.service.UserService))")// 如果是pertarget或perthis,则会多生成一个Advisor并放在最前面// 在一个代理对象调用方法的时候,就会执行该Advisor,并且会利用lazySingletonAspectInstanceFactory来生成一个切面Beanif(!advisors.isEmpty()&& lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()){
Advisor instantiationAdvisor =newSyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);}// Find introduction fields.// 找到哪些字段上加了@DeclareParents注解,把这些字段以及对于的注解解析封装为Advisor,生成代理对象时会把对于的接口添加到ProxyFactory中for(Field field : aspectClass.getDeclaredFields()){
Advisor advisor =getDeclareParentsAdvisor(field);if(advisor != null){
advisors.add(advisor);}}return advisors;}/*
* 解析成Advisor
*/public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,int declarationOrderInAspect, String aspectName){validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());// 拿到当前方法所对应的Pointcut对象,但是注意:如果当前方法上是这么写的@After("pointcut()"),那么此时得到的Pointcut并没有去解析pointcut()得到对应的表达式
AspectJExpressionPointcut expressionPointcut =getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());// 没有pointcut直接返回空!if(expressionPointcut == null){return null;}// expressionPointcut是pointcut// candidateAdviceMethod承载了advicereturnnewInstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,this, aspectInstanceFactory, declarationOrderInAspect, aspectName);}/*
* 解析成Pointcut
*/private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass){// 拿到切面中某个方法上的注解信息
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);if(aspectJAnnotation == null){return null;}// 得到一个AspectJExpressionPointcut对象
AspectJExpressionPointcut ajexp =newAspectJExpressionPointcut(candidateAspectClass,newString[0],newClass<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());if(this.beanFactory != null){
ajexp.setBeanFactory(this.beanFactory);}return ajexp;}
常用的@Before、@Before…解析流程
/**
* 源码入口:org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.getAdvice()
* 当前核心逻辑入口:org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvice(Method, AspectJExpressionPointcut, MetadataAwareAspectInstanceFactory, int, String)
*/public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory,int declarationOrder, String aspectName){// 得到@Aspect注解的信息
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();validate(candidateAspectClass);// 拿到当前candidateAdviceMethod方法上的注解信息
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);if(aspectJAnnotation == null){return null;}// If we get here, we know we have an AspectJ method.// Check that it's an AspectJ-annotated classif(!isAspect(candidateAspectClass)){thrownewAopConfigException("Advice must be declared inside an aspect type: "+"Offending method '"+ candidateAdviceMethod +"' in class ["+
candidateAspectClass.getName()+"]");}if(logger.isDebugEnabled()){
logger.debug("Found AspectJ method: "+ candidateAdviceMethod);}
AbstractAspectJAdvice springAdvice;// 按不同的注解类型得到不同的Adviceswitch(aspectJAnnotation.getAnnotationType()){case AtPointcut:if(logger.isDebugEnabled()){
logger.debug("Processing pointcut '"+ candidateAdviceMethod.getName()+"'");}return null;case AtAround:// @Around
springAdvice =newAspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtBefore:
springAdvice =newAspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtAfter:
springAdvice =newAspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtAfterReturning:
springAdvice =newAspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation =(AfterReturning) aspectJAnnotation.getAnnotation();if(StringUtils.hasText(afterReturningAnnotation.returning())){
springAdvice.setReturningName(afterReturningAnnotation.returning());}break;case AtAfterThrowing:
springAdvice =newAspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation =(AfterThrowing) aspectJAnnotation.getAnnotation();if(StringUtils.hasText(afterThrowingAnnotation.throwing())){
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());}break;default:thrownewUnsupportedOperationException("Unsupported advice type on method: "+ candidateAdviceMethod);}// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames =this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);if(argNames != null){
springAdvice.setArgumentNamesFromStringArray(argNames);}
springAdvice.calculateArgumentBindings();return springAdvice;}