spring源码解析-aop下篇

引子

上一篇spring源码解析-aop第一篇 主要是为读aop代码做技术准备, 一方面了解spring aop与aspectJ之间的关系,另一方面通过多种使用示例了解spring aop工作方式,接下来我们开始分析spring aop的代码。

示例

老规矩,读源码从用例断点开始,虽然spring实现aop有多种方式,但由于springboot使用越来越广泛,开发者也越来越喜欢用注解进行开发,所以我们例子也是纯注解。

//创建一个被代理类
package com.xxx;
@Component
public class Person {
    public String getName() {
        System.out.println("my name is jeff.zou");
        return "jeff";
    }
}
//创建一个代理类
package com.xxx;

@Aspect
@Component
public class PersonInterceptor {

    @AfterReturning(returning = "o", pointcut = "execution(public String com.xxx.Person.getName())")
    public void after(Object o) {
        System.out.println("hello " + o);
    }

}
//测试用例
@Test
public void testAnnotationAspectJ() {
  AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
  applicationContext.scan("com.xxx");
  //启动@Aspect支持 
  applicationContext.register(AnnotationAwareAspectJAutoProxyCreator.class);
  //启动spring
  applicationContext.refresh();
  Person person = (Person) applicationContext.getBean("person");
  person.getName();
}

输出结果:

在测试用例里,启动spring前需要先注册AnnotationAwareAspectJAutoProxyCreator,这个用来开启支持@Aspect注解的,接下来我们从这个类入手解析spring aop源码。

注册processor - AnnotationAwareAspectJAutoProxyCreator

首先看一下AnnotationAwareAspectJAutoProxyCreator的父类关系图:

在这个图里有一个重要的父类BeanPostProcessor,也就是说这个类将被注册成processor,为后续其它bean的创建提供增强功能。

因为之前在讲ioc源码时 spring源码解析-启动流程与循环依赖 ,有分析bean的创建过程,所以这里不一步一步断点说明这个processor的创建过程了,调用refresh()后进入断点,可以看到processor注册结果如下:

spring在beanFacatory初始化时将AnnotationAwareAspectJAutoProxyCreator加入到processor列表里,为后面其它bean的创建提供服务,因为本文重点是分析spring aop的工作原理,所以注册过程就这样简单略过一下了,我们只需要知道spring注册了一个用于生成代理类的creator,接下来我们分析aop工作过程。

创建代理

AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口,这个接口只有两个方法:postProcessBeforeInstantiation与postProcessAfterInstantiation,这两个方法会在bean初始化前后执行,如果它要为其它bean生成代理类就一定会执行这两个方法中的一个,所以直接进入这两个方法断点:

因为它会扫描所有的bean,所以需要你不停的执行,直到你的被代理类出现:

这样我们就进入了创建代理类的核心代码了:

//AbstractAutoProxyCreator.java
@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(beanClass, beanName);

    //条件判断,基础类型不需要代理的忽略
		if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		if (beanName != null) {
			TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
      //判断被代理类是否存在,这里会不存在
			if (targetSource != null) {
				this.targetSourcedBeans.add(beanName);
				Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
				//创建动态代理类
        Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
				this.proxyTypes.put(cacheKey, proxy.getClass());
				return proxy;
			}
		}

		return null;
	}

因为这并不能找到targetSource,所以这里还不会创建代理类,需要等被代理类person写入到第三级缓存中,接下来我们看postProcessAfterInstantiation:

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
      //创建完person bean后,判断是否已经有代理引用了
			if (!this.earlyProxyReferences.contains(cacheKey)) {
        //进入创建代理逻辑
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (beanName != null && 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;
	}

接下来进入createProxy方法:

	protected Object createProxy(
			Class<?> beanClass, String beanName, 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);
			}
		}

    //拿到advisors
		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());
	}

创建代理类前先拿到advisors,也就是示例中PersonInterceptor.java中定义的代理关系,如下图:

在代理工厂里会先执行createAopProxy创建一个代理器,然后用getProxy创建代理。


public Object getProxy(ClassLoader classLoader) {
  //先创建一个代理器
  //再创建代理
   return createAopProxy().getProxy(classLoader);
}

因为示例中被代理类Person.java不是接口,spring会选择cglib来生成代理类:

//CglibAopProxy.java
@Override
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
		}

		try {
      //拿到被代理对象Class
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
			if (ClassUtils.isCglibProxyClass(rootClass)) {
        //父类为被代理对象
				proxySuperClass = rootClass.getSuperclass();
				Class<?>[] additionalInterfaces = rootClass.getInterfaces();
				for (Class<?> additionalInterface : additionalInterfaces) {
					this.advised.addInterface(additionalInterface);
				}
			}
			.................
      
			// 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));
			
      .....................

			// Generate the proxy class and create a proxy instance.
			return createProxyClassAndInstance(enhancer, callbacks);
 		catch (CodeGenerationException ex) {
		..................
      }
    }

上面的代码完成了代理类增强器enhancer(cglib内用于改成代理类class)的设置,接下来就是创建class文件并实例化了:

//ObjenesisCglibAopProxy.java
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
  //生成class
		Class<?> proxyClass = enhancer.createClass();
		Object proxyInstance = null;

		if (objenesis.isWorthTrying()) {
			try {
        //实例化
				proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
			}
			catch (Throwable ex) {
				logger.debug("Unable to instantiate proxy using Objenesis, " +
						"falling back to regular proxy construction", ex);
			}
		}

		if (proxyInstance == null) {
			// Regular instantiation via default constructor...
			try {
				proxyInstance = (this.constructorArgs != null ?
						proxyClass.getConstructor(this.constructorArgTypes).newInstance(this.constructorArgs) :
						proxyClass.newInstance());
			}
			catch (Throwable ex) {
				throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
						"and regular proxy instantiation via default constructor fails as well", ex);
			}
		}

		((Factory) proxyInstance).setCallbacks(callbacks);
		return proxyInstance;
	}

这样代理类生成过程就完成了,spring利用它来完成aop相关的工作。

关注个人微信公众号:肌肉码农,回复“好友”讨论问题。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值