一篇文章让你吃透spring aop底层原理

  • 回顾ioc容器 初始化过程
  • 从@EnableAspectJAutoProxy看起
  • AnnotationAwareAspectJAutoProxyCreator 上下继承关系如下
    • beanpostProcessor 工作原理

看这一遍默认你对spring aop使用非常了解,对动态代理也有一定的了解,如果确实不是很了解请看下面的几篇使用相关的文档

spring 学习之四(spring的注入方式(xml和annotation))

spring学习之五(spring aop编程)

回顾ioc容器 初始化过程

一篇文章让你吃透spring aop底层原理_第1张图片

 

aop其实就是对我们目前的方法进行增强,根据我们以前的知识储备知道 AnnotationAwareAspectJAutoProxyCreator这个类是aop实现的一个比较核心的一个类,这个类也是一个BeanPostProcessor类,这样根据我们对ioc容器初始化就比较容易理解了,

1.在beanBactory初始化过程中将BeanPoster注册到BeanDefinitionMap中

2. Bean在初始化时进行对bean增强, 也就是在init方法前后进行操作

从@EnableAspectJAutoProxy看起

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
 

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies. The default is {@code false}.
	 */
	boolean proxyTargetClass() default false;

	/**
	 * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
	 * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
	 * Off by default, i.e. no guarantees that {@code AopContext} access will work.
	 * @since 4.3.1
	 */
	boolean exposeProxy() default false;

}

@Import(AspectJAutoProxyRegistrar.class) 这个我们知道导入了一个注册类AspectJAutoProxyRegistrar组件

@Import 注解源码参考

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
 

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
 

		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
 
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
 
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
 
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

}

这个方法就是处理我们在使用@EnableAspectJAutoProxy 中的两个属性( exposeProxy proxyTargetClass),默认两个都为false 先不深入了解这个了

@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {
 

		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}

此时将AnnotationAwareAspectJAutoProxyCreator 注册到beandefinitionmap中

@Nullable
	private static BeanDefinition registerOrEscalateApcAsRequired(
			Class cls, BeanDefinitionRegistry registry, @Nullable Object source) {
 

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
 
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
 
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
 
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}

		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

IOC容器中注入了一个internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator的beandefintion,到此可以得出结论,@EnableAspectJAutoProxy给容器中注册一个AnnotationAwareAspectJAutoProxyCreator。

AnnotationAwareAspectJAutoProxyCreator 上下继承关系如下

我们从下图可以知道继承接口BeanFactoryAware 和BeanPostProcessor接口因此我们可以知道在bean初始化时回出发

一篇文章让你吃透spring aop底层原理_第2张图片

 

在此需要关注两点内容:

1)关注后置处理器SmartInstantiationAwareBeanPostProcessor(在bean初始化完成前后做事情)

2)关注自动装配BeanFactory。

通过代码查看,发现父类AbstractAutoProxyCreator中有后置处理器的内容;AbstactAdvisorAutoProxyCreator类中重写了其父类AbstractAutoProxyCreator中setBeanFactory()方法,在AnnotationAwareAspectJAutoProxyCreator类中initBeanFactory()方法完成了自动装配BeanFactory。分别在这两处关注点打断点来查看其流程:

我们知道AbstactAdvisorAutoProxyCreator 初始化时的一个大致过程如下:

一篇文章让你吃透spring aop底层原理_第3张图片

 

setBeanFactory方法和BeanPostProcessorsBeforeInitialization BeanPostProcessorsAfterInitialization 顺序如下图

一篇文章让你吃透spring aop底层原理_第4张图片

 

源码逻辑:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
 
		if (System.getSecurityManager() != null) {
 
			AccessController.doPrivileged((PrivilegedAction) () -> {
 
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
  // 执行aware 中的方法
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
 
			//BeanPostProcessor Before方法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
 
			// init 方法 @PostConstruct init指定方法 InitializingBean等方式
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
 
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
 
			//beanPostProcessor after方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	} 
   
  

invokeAwareMethods

该方法比较简单:

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory
@Override
	public void setBeanFactory(BeanFactory beanFactory) {
 
		super.setBeanFactory(beanFactory);
		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
 
			throw new IllegalArgumentException(
					"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
		}
		initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
	}
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
 
		this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
	}
	子类重写了initBeanFactory方法
@Override
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
 
		super.initBeanFactory(beanFactory);
		if (this.aspectJAdvisorFactory == null) {
 
			this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
		}
		this.aspectJAdvisorsBuilder =
				new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
	}

applyBeanPostProcessorsBeforeInitialization

我看的5.3.x版本的spring 开始没重写 这个before方法

invokeInitMethods

实例化

applyBeanPostProcessorsAfterInitialization

此时看beanpostProcessor 工作原理

1)、传入配置类,创建ioc容器
          2)、注册配置类,调用refresh()刷新容器;
          3)、registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建;
              1)、先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
              2)、给容器中加别的BeanPostProcessor
              3)、优先注册实现了PriorityOrdered接口的BeanPostProcessor;
              4)、再给容器中注册实现了Ordered接口的BeanPostProcessor;
              5)、注册没实现优先级接口的BeanPostProcessor;
              6)、注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中;
                  创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】
                  1)、创建Bean的实例
                  2)、populateBean;给bean的各种属性赋值
                  3)、initializeBean:初始化bean;
                          1)、invokeAwareMethods():处理Aware接口的方法回调
                          2)、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
                          3)、invokeInitMethods();执行自定义的初始化方法
                          4)、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();
                  4)、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;--》aspectJAdvisorsBuilder
              7)、把BeanPostProcessor注册到BeanFactory中;
                  beanFactory.addBeanPostProcessor(postProcessor);  =======以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程========

aop创建对象原理

从上面我分析的逻辑和前置知识非常清楚,当我们自己编写的类填写@EnableAspectJAutoProxy或者通过其他方式开启aop都是在docreateBean方法中进行增强:

我们在这个方法入口打断点 使用断点的方式进行跟踪分析:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

exposedObject = initializeBean(beanName, exposedObject, mbd);

这个方法上面我都分析了aware相关的方法, before init after方法,由于 自己的类非aware ,因此不会执行, before没有重写, 因此不重要下面直接after方法

一篇文章让你吃透spring aop底层原理_第5张图片

进来的时候实体对象不是代理对象,我们继续往下看从哪里开始处理成的代理对象的

beanpostProcessor 工作原理

从上面分析我们可以知道Spring入住了AnnotationAwareAspectJAutoProxyCreator 一个BeanPostProcessor类,又知道改类没有重写before方法,因此after方法才是我们的重点:

重写 beanpostprocessor的after方法

org.springframework.aop.framework.autoproxy.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) {
 
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

一篇文章让你吃透spring aop底层原理_第6张图片

这个地方是二级缓存中存在,删除进行创建对象,ps:二级缓存中存放的是只进行实例化,没有进行初始化的对象

postProcessAfterInitialization方法会对切面进行一次包装的处理。

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.
		//获取我们配置的切面 根据切面进行动态代理
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
 
			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;
	}

下面进行创建代理对象

第一步:创建代理对象的ProxyFactory 工厂

第二步:使用工厂模式创建代理对象

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);
		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);
	}

proxyFactory 工厂拿到了目标对象和定义的切点信息 封装放到这个对象Advisor

我们细看创建代理对象的过程,发现在创建之前首先会根据切入点表达式对增强器进行一一匹配,最终拿到所有的增强器。

创建代理对象:

我们又知道spring创建代理对象有两种方式:jdk动态代理和cglib动态代理

public Object getProxy(@Nullable ClassLoader classLoader) {
 
		return createAopProxy().getProxy(classLoader);
	}

spring 是通过AdvisedSupport 类获取当前用户配置的方式,spring默认使用cglib动态代理

@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
 
		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.");
			}
			//如果目标类是接口或者代理类 使用jdk代理
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
 
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
 
			return new JdkDynamicAopProxy(config);
		}
	}

真正获取代理对象的地方cglib代理方式

org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
//根据目标对象获取一堆拦截器
//这就是给代理对象增强的核心代码
Callback[] callbacks = getCallbacks(rootClass);

Callback[] callbacks = getCallbacks(rootClass);

这个地方先混个眼熟,到调用方法时会使用这些拦截器

一篇文章让你吃透spring aop底层原理_第7张图片

上面我们就把代理类生产了并且放到容器beanmap里面了

其中生产的过程自己断点看看吧 这个地方我们只看了一个cglib方式生产,底层使用的asm 比较复杂,这里就不再赘述.

调用方法

获取该对象看看代理对象中包含很多拦截器因此先进拦截器中

一篇文章让你吃透spring aop底层原理_第8张图片

这个时候拦截器就起作用了直接进入下面的方法

org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept
//获取可以应用到此方法上的Interceptor列表
				List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
				Object retVal;
				else {
 
					// We need to create a method invocation...
					retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
				}
				retVal = processReturnType(proxy, target, method, retVal);
				return retVal; 
   
  

一篇文章让你吃透spring aop底层原理_第9张图片

private static class CglibMethodInvocation extends ReflectiveMethodInvocation {

反射机制 掉用proceed 走父类的

ReflectiveMethodInvocation

通过反射就可以在执行代码的前后进行增强了

这个地方自己不是很熟悉的可以自己看看 反射和动态代理相关的知识

你可能感兴趣的:(spring,spring,java,后端)