注解Spring AOP源码解析

创建代理对象

@EnableAspectJAutoProxy

如果需要开启aop功能,那么通常都在主配置类添加 @EnableAspectJAutoProxy 注解,这个注解会为我们在容器中导入一个 AspectJAutoProxyRegistrar 组件。

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

AspectJAutoProxyRegistrar 实现了ImportBeanDefinitionRegistrar 接口,它在创建容器 refresh 方法中的invokeBeanFactoryPostProcessors (执行BeanFactory后置处理器)方法中执行类内的registerBeanDefinitions 方法,即向容器注册 AnnotationAwareAspectJAutoProxyCreator 组件。

AnnotationAwareAspectJAutoProxyCreator

继承体系

AnnotationAwareAspectJAutoProxyCreator

	extends AspectJAwareAdvisorAutoProxyCreator

		extends AbstractAdvisorAutoProxyCreator

			extends AbstractAutoProxyCreator

				extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor,BeanFactoryAware

					extends InstantiationAwareBeanPostProcessor,Aware

						extends BeanPostProcessor

由继承体系,可以知道的是 AnnotationAwareAspectJAutoProxyCreator 是一个bean后置处理器,能在Bean初始化前后对Bean进行相应的处理。

Spring创建bean,在初始化阶段,也就是在执行下面这个代码时

exposedObject = initializeBean(beanName, exposedObject, mbd);

在bean执行完 invokeInitMethods 方法后,也就是初始化后,会调用所有后置处理器的 postProcessAfterInitialization 方法

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

因为AnnotationAwareAspectJAutoProxyCreator也是BeanPostProcessor类型,也会执行方法;并且 AnnotationAwareAspectJAutoProxyCreatorpostProcessAfterInitialization方法会调用wrapIfNecessary方法。

wrapIfNecessary

//该方法在AbstractAutoProxyCreator类中
	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;
	}
  • 该方法首先判断bean对象是否已经是增强bean,如果是,就直接返回;
  • 判断该bean是否不需要增强,如AdvicePointcutAdvisorAopInfrastructureBean 类型的bean就不需要增强,不需要增强,直接返回;advisedBeans 用来保存bean是否需要增强;
  • 获取该类可以增强的Advisor
  • 调用createProxy 方法,创建代理对象;

createProxy

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

   return proxyFactory.getProxy(getProxyClassLoader());
}
  • 创建ProxyFactory,代理对象就是由它创建的;
  • specificInterceptors中所有的增强器封装为Advisor
  • ProxyFactory中添加advisors属性;
  • 调用proxyFactory.getProxy创建代理对象,该方法最后会调用DefaultAopProxyFactorycreateAopProxy 方法

createAopProxy

//该方法在DefaultAopProxyFactory中
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)) {
         return new JdkDynamicAopProxy(config);
      }
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      return new JdkDynamicAopProxy(config);
   }
}
  • 首先进行了条件判断,具体见下
    • config.isOptimize():判断通过CGLIB创建的代理是否使用了优化策略。该条件取值于ProxyConfigoptimize属性。此属性标记是否对代理进行优化。启动优化意味着直接优先采用CGLIB代理,默认值为false。
    • config.isProxyTargetClass():是否配置了proxy-target-class为true。该条件取值于ProxyConfig类的proxyTargetClass属性。此属性标记是否直接对目标类进行代理,而不是通过接口产生代理。
    • hasNoUserSuppliedProxyInterfaces(config):是否不存在代理接口。

如果这些条件有一个为true,就进一步判断,如果都为false,就采用JDK代理方式。

  • targetClass.isInterface() :用来判断目标对象是否为接口。
  • Proxy.isProxyClass(targetClass) :目标类是否是已代理对象
    如果满足以上两个要求的其中一个就采用JDK代理方式;都不满足采用CGLIB方式。

总结一下:如果目标类没有接口实现且本身不是接口或已代理对象,就采用CGLIB动态代理,其他情况都采用JDK动态代理。可以通过proxy-target-class设置是否使用CGLIB代理。

这里返回了一个包装对象,其中有目标对象和所有可以使用的增强器advisor。

getProxy

	@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
		...
		
		try {
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

			Class<?> proxySuperClass = rootClass;
			if (ClassUtils.isCglibProxyClass(rootClass)) {
				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 instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
			enhancer.setSuperclass(proxySuperClass);
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
			enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

			Callback[] callbacks = getCallbacks(rootClass);
			Class<?>[] types = new Class<?>[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(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
			enhancer.setCallbackTypes(types);

			// Generate the proxy class and create a proxy instance.
			return createProxyClassAndInstance(enhancer, callbacks);
		}
		catch (CodeGenerationException | IllegalArgumentException ex) {
			throw new AopConfigException("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() failed
			throw new AopConfigException("Unexpected AOP exception", ex);
		}
	}
  • 创建Enhancer对象,并进行相关设置;
  • 将包装类的advisor包装为拦截器;
  • 根据interceptor数组和enhancer动态代理创建了一个代理实例(createProxyClassAndInstance 方法中);

此时,代理对象就创建完成了,其中代理对象中有拦截器。

动态代理创建对象总结

aop创建代理对象的关键在于AnnotationAwareAspectJAutoProxyCreator这个后置处理器,在对象初始化完全后会调用其初始化后置方法对bean进行增强;增强主要包括获取相应的advisor并将其包装为一个ProxyFactory对象,然后根据这个对象进行动态代理,并在代理对象中设置相应的拦截器(advisor包装后的对象interceptor)。

代理对象方法的执行

在执行目标方法时,会被代理器中的拦截器DynamicAdvisedInterceptor拦截,执行其intercept方法。

intercept方法

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
   Object oldProxy = null;
   boolean setProxyContext = false;
   Object target = null;
   TargetSource targetSource = this.advised.getTargetSource();
   try {
		...
      // 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);
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
      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...
         retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
      }
      retVal = processReturnType(proxy, target, method, retVal);
      return retVal;
   }
   ...
}
  • 获取源对象和拦截器链;
  • 如果拦截器链长度为空,就反射调用源方法,如果不为空,执行相应的拦截器链;
  • 获取返回值;

proceed方法

proceed是拦截方法生效的关键

	public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		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);
		}
	}

currentInterceptorIndex初始值为-1

  • 第一个if判断拦截器链的长度是否为0,如果为0,就反射执行目标方法;
  • 获取下标为0的相应拦截器(ExposeInvocationIntecerptor),执行它的invoke方法
	public Object invoke(MethodInvocation mi) throws Throwable {
		MethodInvocation oldInvocation = invocation.get();
		invocation.set(mi);
		try {
			return mi.proceed();
		}
		finally {
			invocation.set(oldInvocation);
		}
	}

这里的invocation是一个ThreadLocal,也就是用来存储本线程的变量;

invocation.set(mi);

threadLocal设置ReflectiveMethodInvocation对象,key为ExposeInvocationInterceptor,value为ReflectiveMethodInvocation
再次调用ReflectiveMethodInvocationproceed方法,然后依次调用AspectJAfterThrowingAdviceAfterReturningAdviceInterceptorAspectJAfterAdviceMethodBeforeAdviceInterceptorinvoke方法,其中都调用了ReflectiveMethodInvocationproceed方法。

这里有点像DFS(深度遍历),具体见下图
在这里插入图片描述

总结

代理方法的执行主要包括获取拦截方法和目标方法,然后采用递归的方式后续遍历依次调用拦截器的invoke方法,然后在后续操作中执行相应的方法。

基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip 个人大四的毕业设计、课程设计、作业、经导师指导并认可通过的高分设计项目,评审平均分达96.5分。主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 [资源说明] 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设或者课设、作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),供学习参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值