spring源码分析之AOP v1.0

第一节 参考

spring架构,Bean创建加载前的过程参考<spring源码分析之架构和Refresh>

第二节 架构     


一.启动

1.springboot使用aop时,用@EnableAspectJAutoProxy注解实现.在@EnableAspectJAutoProxy注解
上面有@Import(AspectJAutoProxyRegistrar.class)。@import作用和@Configuration类似. spring启动
时通过AspectJAutoProxyRegistrar类扫描aop的实现类AnnotationAwareAspectJAutoProxyCreator.
AspectJAutoProxyRegistrar类实现了ImportBeanDefinitionRegistrar 接口,spring可以通过这个接口向beanDefinationMap中添加bean的定义.
2.核心处理类是AnnotationAwareAspectJAutoProxyCreator.它继承自AspectJAwareAdvisorAutoProxyCreator,继承自AbstractAdvisorAutoProxyCreator,继承自AbstractAutoProxyCreator.在AbstractAutoProxyCreator#postProcessAfterInitialization()方法中进行aop的匹配检测,创建代理对象.

第三节 源码细节 
一.启动 
(一).读取aop属性.
因为@Import(AspectJAutoProxyRegistrar.class),spring启动时进入AspectJAutoP
roxyRegistrar#registerBeanDefinitions方法,启动时的堆栈如下图:

AspectJAutoProxyRegistrar#registerBeanDefinitions代码如下:
 

public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    //注册AnnotationAwareAspectJAutoProxyCreator类到beanDefinitionMap中。
	AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
	//获取是否接口也走CGLib
	AnnotationAttributes enableAspectJAutoProxy =
			AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
	if (enableAspectJAutoProxy != null) {
		if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
			AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
		}
		if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
			AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
		}
	}
}

(二).创建代理对象.
1.在createBean()方法调用时,填充完属性,到初始化阶段,调用postProcessBeforeInitialization()
回调之前,进入initializeBean()->invokeAwareMethods(),进入AbstractAdvisorAutoProxyCreator#setBeanFactory()
把Bean工厂,即DefaultListableBeanFactory设置到AbstractAutoProxyCreator#beanFactory成员中.
2.调用初始化方法的after回调,进入AbstractAutoProxyCreator#postProcessAfterInitialization(),
开始创建代理对象.在createBean()返回时就返回这个代理对象放入到DefaultSingletonBeanRegistry#singletonObjects中.代理对象如下图:

进入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;
}

创建代理.
 

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;
	}
	//如果是AopInfrastructureBean,Advisor,Pointcut,Advice,这些aop的基础类,直接跳过
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	// Create proxy if we have advice.
	//判断是否需要代理,在后面代码3处分析
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	/* 如果需要aop拦截, 加到AbstractAutoProxyCreator#advisedBeans,AbstractAutoProxyCreator#proxyTypes两个成员中,*/
	if (specificInterceptors != DO_NOT_PROXY) {
		//需要aop代理
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		//创建代理对象,在后面4处分析
		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;
}

3.判断是否需要代理.进入AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean()方法.
 

protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
	//判断是否有代理的注解,代码在后面分析
	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	if (advisors.isEmpty()) {
		return DO_NOT_PROXY;
	}
	return advisors.toArray();
}

//判断是否有代理的注解.进入AbstractAdvisorAutoProxyCreator#findEligibleAdvisors()方法.
 

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	/* 查找所有的Advisor,返回InstantiationModelAwarePointcutAdvisorImpl对象列表,测试时写了两个,一个before,一个around */
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	/*
	遍历所有的Advisor,看是否能拦截代理当前方法,代码在后面分析
	*/
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

//遍历所有的Advisor,看是否能拦截代理目标类,进入AopUtils#findAdvisorsThatCanApply()方法.
 

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
	//候选的Advisor列表为空,直接返回.
	if (candidateAdvisors.isEmpty()) {
		return candidateAdvisors;
	}
	List<Advisor> eligibleAdvisors = new ArrayList<>();
	for (Advisor candidate : candidateAdvisors) {
		//如果是IntroductionAdvisor类型,进入AopUtils#canApply()方法,判断是否匹配目标类。
		if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
			eligibleAdvisors.add(candidate);
		}
	}
	boolean hasIntroductions = !eligibleAdvisors.isEmpty();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor) {
			// already processed
			continue;
		}
		//测试类时,进入这里判断目标类是否匹配.aop不是IntroductionAdvisor类型的,属于PointcutAdvisor类型。代码如下。
		if (canApply(candidate, clazz, hasIntroductions)) {
			eligibleAdvisors.add(candidate);
		}
	}
	return eligibleAdvisors;
}

进入AopUtils#canApply(),判断单个Advisor和目标类是否匹配.
 

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
	Assert.notNull(pc, "Pointcut must not be null");
	if (!pc.getClassFilter().matches(targetClass)) {
		return false;
	}

	//获取aop的方法.即方法上面注解了execution的方法,上面记录了拦截哪些方法.
	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<>();
	//目标类如果不是代理类,添加到代理目标列表classes中.
	if (!Proxy.isProxyClass(targetClass)) {
		classes.add(ClassUtils.getUserClass(targetClass));
	}
	classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

	for (Class<?> clazz : classes) {
		Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
		/* 遍历目标类的所有方法,调用AspectJExpressionPointcut#matches(),判断方法和execution记录的是否匹配.具体匹配逻辑是调用AspectJExpressionPointcut#getShadowMatch(),进入aspectjweaver库的org.aspectj.weaver.tools.PointcutExpression#matchesMethodExecution()方法做匹配. */
		for (Method method : methods) {
			if (introductionAwareMethodMatcher != null ?
					introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
					methodMatcher.matches(method, targetClass)) {
				return true;
			}
		}
	}

	return false;
}

4.满足aop拦截路径的类,创建代理,在前面的2调用进来.
进入AbstractAutoProxyCreator#createProxy()方法.代码如下:
 

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
	//DefaultListableBeanFactory满足进入
	if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
		//设置AutoProxyUtils#ORIGINAL_TARGET_CLASS_ATTRIBUTE属性为被代理的原对象,比如helloService
		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,一个拦截方法是一个Advisor
	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	proxyFactory.addAdvisors(advisors);
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);

	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}

	//调用jdk或者cglib获取代理对象.在getProxy()中调用ProxyCreatorSupport#createAopProxy()方法代码在后面
	return proxyFactory.getProxy(getProxyClassLoader());
}

判断使用哪种代理,创建代理对象
 

public Object getProxy(@Nullable ClassLoader classLoader) {
	/* createAopProxy(),返回使用哪种代理方式. 
	   getProxy()获取代理对象.
	*/
	return createAopProxy().getProxy(classLoader);
}

判断使用哪种代理方式,进入DefaultAopProxyFactory#createAopProxy()方法.
 

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	/*如果配置了proxyTargetClass=true,走cglib*/
	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.");
		}
		//目标对象是接口,走cglib.
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		//默认返回jdk代理对象
		return new JdkDynamicAopProxy(config);
	}
}

测试中,我的目标类不是接口,进入CglibAopProxy#getProxy()创建代理对象.
 

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 (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类创建代理对象,cglib的使用方式.
		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 ClassLoaderAwareGeneratorStrategy(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) {
		...
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值