• spring5.3 十四:spring AOP源码分析


    AOP源码分析

    上一篇分析过spring 通过ProxyFactory来创建代理对象。下面来分析下ProxyFactory的原理

    ProxyFactory源码分析

    上一篇aop的介绍中有提到这两行代码

    ProxyFactory proxyFactory = new ProxyFactory();
    BookInterface bookInterface = (BookInterface)proxyFactory.getProxy();
    
    • 1
    • 2

    关键是getProxy方法。

    public Object getProxy(@Nullable ClassLoader classLoader) {
    		return createAopProxy().getProxy(classLoader);
    	}
    protected final synchronized AopProxy createAopProxy() {
    		if (!this.active) {
    			activate();
    		}
    		// 默认为DefaultAopProxyFactory
    		return getAopProxyFactory().createAopProxy(this);
    	}
    //最终调到这个方法 通过该方法判断是通过cglib代理还是jdk代理
    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    		// 如果ProxyFactory的isOptimize为true,
    		// 或者isProxyTargetClass为true,
    		// 或者被代理对象没有实现接口,
    		// 或者只实现了SpringProxy这个接口
    		// 那么则利用Cglib进行动态代理,但如果被代理类是接口,或者被代理类已经是进行过JDK动态代理而生成的代理类了则只能进行JDK动态代理
    
    		// 其他情况都会进行JDK动态代理,比如被代理类实现了除SpringProxy接口之外的其他接口
    
    		if (!NativeDetector.inNativeImage() &&
    				(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);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    决定好通过那个方式进行代理后,真正调getProxy()方法由下面两个实现类
    在这里插入图片描述
    这里通过jdk的动态代理为例子

    spring中jdk动态代理源码分析

    JdkDynamicAopProxy这个类就是jdk动态代理源码。

    @Override
    	public Object getProxy(@Nullable ClassLoader classLoader) {
    		if (logger.isTraceEnabled()) {
    			logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
    		}
    		// this实现了InvocationHandler
    		return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这个方法就是放回一个代理对象,不做过多分析。jdk动态代理中,执行代理逻辑和目标方法是通过invoke方法

    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()方法,那么则直接调用,不走代理
    			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
    				return equals(args[0]);
    			}
    			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
    				return hashCode();
    			}
    			else if (method.getDeclaringClass() == DecoratingProxy.class) {
    				// 得到代理对象的类型,而不是所实现的接口
    				return AopProxyUtils.ultimateTargetClass(this.advised);
    			}
    			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
    					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
    				// 也是直接调用Advised接口中的方法,不走代理逻辑
    				// 其实就是利用代理对象获取ProxyFactory中的信息
    				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
    			}
    			Object retVal;
    			// 如果ProxyFactory的exposeProxy为true,则将代理对象设置到currentProxy这个ThreadLocal中去
    			if (this.advised.exposeProxy) {
    				// Make invocation available if necessary.
    				oldProxy = AopContext.setCurrentProxy(proxy);
    				setProxyContext = true;
    			}
    			// 被代理对象和代理类
    			target = targetSource.getTarget();
    			Class<?> targetClass = (target != null ? target.getClass() : null);
    			//获取被代理对象和执行的方法对应的代理逻辑链路
    			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    			if (chain.isEmpty()) {
    				// 如果没有代理逻辑,则直接调用对应方法
    				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
    				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
    			}
    			else {
    				//把代理逻辑链路 和代理对象 执行的方法 入参 等封装成MethodInvocation对象
    				MethodInvocation invocation =
    						new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
    				// Proceed to the joinpoint through the interceptor chain.
    				retVal = invocation.proceed();
    			}
    			Class<?> returnType = method.getReturnType();
    			if (retVal != null && retVal == target &&
    					returnType != Object.class && returnType.isInstance(proxy) &&
    					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
    				retVal = proxy;
    			}
    			else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
    				throw new AopInvocationException(
    						"Null return value from advice does not match primitive return type for: " + method);
    			}
    			return retVal;
    		}
    		finally {
    			if (target != null && !targetSource.isStatic()) {
    				targetSource.releaseTarget(target);
    			}
    			if (setProxyContext) {
    				AopContext.setCurrentProxy(oldProxy);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    整个方法的大致流程是:过滤掉equal()、hashcode()这两个方法,这两个方法执行不触发代理逻辑。判断代理类型,执行对应代码。各种判断通过后,List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);方法拿到所有的代理逻辑链路。没有代理逻辑执行目标方法。有代理逻辑,把每个代理逻辑加上代理对象,入参等封装成MethodInvocation对象执行invocation.proceed();方法。
    这个过程中核心部分有两个getInterceptorsAndDynamicInterceptionAdvice方法拿到所有代理逻辑。proceed()真正去执行代理逻辑。那么接下来分析如何获取所有代理逻辑和如何去执行
    如何获取所有代理逻辑
    getInterceptorsAndDynamicInterceptionAdvice这个方法最终调到DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice方法

    @Override
    	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)
    		// 添加的时候会控制顺序
    		Advisor[] advisors = config.getAdvisors();
    		List<Object> interceptorList = new ArrayList<>(advisors.length);
    		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
    		Boolean hasIntroductions = null;
    
    		for (Advisor advisor : advisors) {
    			if (advisor instanceof PointcutAdvisor) {
    				// Add it conditionally.
    				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
    				// 先匹配类
    				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
    
    					// 再匹配方法
    					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
    					boolean match;
    					if (mm instanceof IntroductionAwareMethodMatcher) {
    						if (hasIntroductions == null) {
    							hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
    						}
    						match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
    					}
    					else {
    						match = mm.matches(method, actualClass);
    					}
    
    					// 如果匹配则将Advisor封装成为Interceptor
    					if (match) {
    						//该方法使用了适配器模式,根据配置的切面逻辑类型 BeforeAdvice 、AroundAdvice等等 封装成Interceptor
    						MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
    						if (mm.isRuntime()) {
    							// Creating a new object instance in the getInterceptors() method
    							// isn't a problem as we normally cache created chains.
    							for (MethodInterceptor interceptor : interceptors) {
    								interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
    							}
    						}
    						else {
    							interceptorList.addAll(Arrays.asList(interceptors));
    						}
    					}
    				}
    			}
    			else if (advisor instanceof IntroductionAdvisor) {
    				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;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    这个过程大致是:从ProxyFactory 拿到所有代理逻辑,不管在ProxyFactory 中配置的是addAdvice()还是addAdvisor()都会封装成Advisor。遍历所有代理逻辑,判断该代理逻辑是满足切点(源码中先判断 是否满足被代理的类 ,再判断是否满足被代理的方法)。匹配通过会把所有通过的代理逻辑封装成Interceptor。
    如何调用
    找到那些代理逻辑需要被调用后。通过invocation.proceed();进行调用

    public Object proceed() throws Throwable {
    		// currentInterceptorIndex初始值为-1,每调用一个interceptor就会加1
    		// 当调用完了最后一个interceptor后就会执行被代理方法
    		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    			return invokeJoinpoint();
    		}
    		//都拿到对应的代理逻辑
    		Object interceptorOrInterceptionAdvice =
    				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    		// 当前interceptor是InterceptorAndDynamicMethodMatcher,则先进行匹配,匹配成功后再调用该interceptor
    		// 如果没有匹配则递归调用proceed()方法,调用下一个interceptor
    		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
    			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 {
    			// 直接调用MethodInterceptor,传入this,在内部会再次调用proceed()方法进行递归
    			// 比如MethodBeforeAdviceInterceptor
    			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    整个流程大概是:判断当前执行完的代理逻辑是不是最后一个,如果是执行代理方法。如果不是执行代理逻辑,执行代理逻辑之前会进行类型判断。类型判断未通过递归执行invoke方法,接着判断下一个代理逻辑。判断通过后还有进行方法入参的判断。判断通过执行对应的代理逻辑。

    上面这些过程都是ProxyFactory的过程。那么在spring中的Aop流程是怎么使用这个ProxyFactory的呢

    springAOP流程源码分析

    下面通过spring源码分析上一篇中使用到AOP代码。

    @EnableAspectJAutoProxy
    @Configuration
    public class AopConfig {}
    @Component
    @Aspect
    public class MyAspect {
    	@Before("execution(public void aop.BookService.book())")
    	public void myBefore(JoinPoint joinPoint) {
    		System.out.println("myBefore --- BookService init");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其中@EnableAspectJAutoProxy的代码

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({AspectJAutoProxyRegistrar.class})
    public @interface EnableAspectJAutoProxy {
        boolean proxyTargetClass() default false;
    
        boolean exposeProxy() default false;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    主要是引入了AspectJAutoProxyRegistrar.class。这个类呢主要就给spring容器中注册AnnotationAwareAspectJAutoProxyCreator这个类。并且根据@EnableAspectJAutoProxy的属性值给这个类对应的属性赋值。
    在这里插入图片描述
    根据类关系图可以看出AnnotationAwareAspectJAutoProxyCreator实际上是一个BeanPostProcessor。注册这个AnnotationAwareAspectJAutoProxyCreator实际上就是注册了一个BeanPostProcessor。在spring生命周期中分析过 。BeanPostProcessor在初始化后执行会执行postProcessAfterInitialization方法。在这里执行的是AbstractAutoProxyCreator.postProcessAfterInitialization方法。

    	@Override
    	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    		if (bean != null) {
    			Object cacheKey = getCacheKey(bean.getClass(), beanName);
    			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
    				//核心方法 基于当前bean创建代理对象
    				return wrapIfNecessary(bean, beanName, cacheKey);
    			}
    		}
    		return bean;
    	}
    
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    
    		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
    			//这个bean已经是代理类 直接返回
    			return bean;
    		}
    		//advisedBeans表示已经判断过的bean 和下面一个if有关
    		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
    			//已经判断过的bean 不需要代理 直接返回
    			return bean;
    		}
    		//isInfrastructureClass(bean.getClass()) 符合这些(Pointcut.class 、Advisor.class 、Advisor.class等)类型的bean不需要aop
    		// 当前正在创建的Bean不用进行AOP,比如切面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) {
    			// advisedBeans记录了某个Bean已经进行过AOP了
    			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;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    wrapIfNecessary这个过程就是:通过一些条件判断哪些类需要AOP,哪些类不需要AOP。如果需要AOP,核心部分有两个

    • Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);获取所有匹配的切面‘’
    • 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);
    
    		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);
    		// 如果使用了@DeclareParents,那么在添加advisor时,会把对应的接口添加到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 instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
    			classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
    		}
    		return proxyFactory.getProxy(classLoader);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    底层就是通过ProxyFactory来创建代理对象。这也是为什么有先铺垫ProxyFactory的原因。这里就不在分析了。

    接下来看如何获取切面
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

    protected Object[] getAdvicesAndAdvisorsForBean(
    			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    		// 寻找匹配的Advisor
    		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    		if (advisors.isEmpty()) {
    			return DO_NOT_PROXY;
    		}
    		return advisors.toArray();
    	}
    
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    		// 找到所有的Advisor
    		List<Advisor> candidateAdvisors = findCandidateAdvisors();
    		// 进行筛选
    		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    		//子类扩展 可以忽略
    		extendAdvisors(eligibleAdvisors);
    
    		// 对Advisor进行排序,按Ordered接口、@Order注解进行排序
    		if (!eligibleAdvisors.isEmpty()) {
    			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    		}
    		return eligibleAdvisors;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    从上面源码来看 如何获取切面 大致分为三个步骤,

    • 第一步 找到所有的切面 findCandidateAdvisors();
    • 第二步进行筛选 indAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    • 第三步排序 sortAdvisors(eligibleAdvisors);

    findCandidateAdvisors()

    @Override
    	protected List<Advisor> findCandidateAdvisors() {
    		// Add all the Spring advisors found according to superclass rules.
    		// 先找到所有Advisor类型的Bean对象
    		List<Advisor> advisors = super.findCandidateAdvisors();
    
    		// Build Advisors for all AspectJ aspects in the bean factory.
    		// 再从所有切面中解析得到Advisor对象 就是解析@Aspect注解的类下面的@Before等注解
    		if (this.aspectJAdvisorsBuilder != null) {
    			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    		}
    		return advisors;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这一个步流程就是从spring容器中找出所有的bean判断哪些bean是Advisor类型。通过判断哪些Advisor类型的bean有@Aspect注解,解析@Aspect注解的bean里面的@Before等注解

    ** indAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);**
    该方法底层核心筛选代码就是canApply,通过该方法返回boolean值判断符不符合要求

    public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    		Assert.notNull(pc, "Pointcut must not be null");
    		// 判断targetClass是不是和当前Pointcut匹配
    
    		// 先判断类
    		if (!pc.getClassFilter().matches(targetClass)) {
    			return false;
    		}
    
    		MethodMatcher methodMatcher = pc.getMethodMatcher();
    		if (methodMatcher == MethodMatcher.TRUE) {
    			// No need to iterate the methods if we're matching any method anyway...
    			return true;
    		}
    
    		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
    			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    		}
    
    		Set<Class<?>> classes = new LinkedHashSet<>();
    		if (!Proxy.isProxyClass(targetClass)) {
    			classes.add(ClassUtils.getUserClass(targetClass));
    		}
    		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
    
    		for (Class<?> clazz : classes) {
    			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
    			for (Method method : methods) {
    				if (introductionAwareMethodMatcher != null ?
    						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
    						// 在判断方法是否匹配
    						methodMatcher.matches(method, targetClass)) {
    					return true;
    				}
    			}
    		}
    
    		return false;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    主要也是从类 和方法这两方面进行判断。不在深入分析。

    最后进行切面的排序,根据@order注解进行排序也不深入分析。到此SpringAOP流程就结束了
    Spring中AOP原理流程图:https://www.processon.com/view/link/5faa4ccce0b34d7a1aa2a9a5
    下面来总结一下

    总结

    1. 当使用@Aspect进行切面配置的时候需要添加@EnableAspectJAutoProxy表示启动@Aspect的切面配置。原理就是引入了AspectJAutoProxyRegistrar.class
    2. AspectJAutoProxyRegistrar.class向Spring容器中注册了AnnotationAwareAspectJAutoProxyCreator。其父类是BeanPostProcessor类型。在bean的生命周期中的初始化后阶段会执行postProcessAfterInitialization方法。对应上的实现就是AbstractAutoProxyCreator.postProcessAfterInitialization方法。
    3. AbstractAutoProxyCreator.postProcessAfterInitialization方法作用就是判断当前类需要不需要AOP,如果需要返回代理对象,如果不需要返回原始bean对象。其核心方法是wrapIfNecessary
    4. wrapIfNecessary核心步骤有两个 一个找出所有匹配这个bean的切面,另一个是生成代理对象
    5. 找出所有匹配这个bean的切面分为三个步骤 1:找出所有的切面 2:筛选切面 3:切面排序
    6. 当找到匹配的切面后,通过ProxyFactory创建代理对象。到此bean的代理对象就创建完毕
  • 相关阅读:
    精研科技融入汽车内饰 Laedana打造车内空间新生态
    CentOS LVM缩容与扩容步骤
    2022年4月最新面经答案总结(Java基础、数据库、JVM、计网、计操、集合、多线程、Spring)持续更新
    [Vue3] 滚动条自动滚动到底部
    一个web请求在springboot经历了什么
    三、综合——计算机应用基础
    bit byte 和各进制关系(位、字节、字符、进制)、常见编码格式
    【C++】泛型算法(六)Map和Set的使用
    大厂Java岗面试原题复盘,双非2年经验成功内推进入阿里
    寒假训练——第三周(线性DP)
  • 原文地址:https://blog.csdn.net/admin522043032/article/details/126309299