Spring AOP源码深度剖析:如何创建代理对象?这篇文章告诉你!

目录

  • 一、AOP基础用例准备
  • 二、时机点分析
  • 三、代理对象创建流程

一、AOP基础用例准备

Bean定义

@Component
public class LagouBean {
     

 	public void tech(){
     
 	System.out.println("java learning......");
 	}
}

Aspect定义

package com.lagou;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LagouAspect {
     
 	@Pointcut("execution(* com.lagou.*.*(..))")
 	public void pointcut(){
     
}
 
@Before("pointcut()")
public void before() {
     
	System.out.println("before method ......");
	}
}

测试用例

/**
* 测试用例:Aop 代理对象创建
*/
@Test
public void testAopProxyBuild(){
     
 	ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
 	LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
 	lagouBean.tech();
}

本文参考资料《Spring高级源码笔记》,需要的同学添加助理VX:C18173184271,备注一下CSDN+工作年限!免费获取

二、时机点分析

Spring AOP源码深度剖析:如何创建代理对象?这篇文章告诉你!_第1张图片
我们发现在 getBean 之前,LagouBean对象已经产生(即在第一行初始化代码中完成),而且该对象是一个代理对象(Cglib代理对象),我们断定,容器初始化过程中目标Ban已经完成了代理,返回了代理对象。

三、代理对象创建流程

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

/**
 	*
 	* 初始化Bean
 		包括Bean后置处理器初始化
		Bean的一些初始化方法的执行init-method
		Bean的实现的声明周期相关接口的属性注入
 */
protected Object initializeBean(final String beanName, final Object bean,
@Nullable RootBeanDefinition mbd) {
     
 	// 执行所有的AwareMethods
 	if (System.getSecurityManager() != null) {
     
 		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
     
 			invokeAwareMethods(beanName, bean);
 			return null;
 		}, getAccessControlContext());
 	}
 	else {
     
 		invokeAwareMethods(beanName, bean);
 	}
 	
 	Object wrappedBean = bean;
 	if (mbd == null || !mbd.isSynthetic()) {
     
 		// 执行所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器方法
 		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName);
	}
	
 	try {
     
 		// 这里就开始执行afterPropertiesSet(实现了InitializingBean接口)方法和initMethod
 		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()) {
     
 		// 整个Bean初始化完成,执行后置处理器方法
 		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean,beanName);
 	}
 	return wrappedBean; 
}

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

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

Spring AOP源码深度剖析:如何创建代理对象?这篇文章告诉你!_第2张图片
创建代理对象的后置处理器AbstractAutoProxyCreator#postProcessAfterInitialization

/**
 * Create a proxy with the configured interceptors if the bean is
 * identified as one to proxy by the subclass.
 * @see #getAdvicesAndAdvisorsForBean
 */

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName){
     
	if (bean != null) {
     
		// 检查下该类是否已经暴露过了(可能已经创建了,比如A依赖B时,创建A时候,就会先去创建B。
		// 当真正需要创建B时,就没必要再代理一次已经代理过的对象),避免重复创建
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
     
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

AbstractAutoProxyCreator#wrapIfNecessary

/**
 * Wrap the given bean if necessary, i.e. if it is eligible for being
proxied.
 * @param bean the raw bean instance
 * @param beanName the name of the bean
 * @param cacheKey the cache key for metadata access
 * @return a proxy wrapping the bean, or the raw bean instance as-is
 */
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
     
	// targetSourcedBeans包含,说明前面创建过
	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.
	// 得到所有候选Advisor,对Advisors和bean的方法双层遍历匹配,最终得到一个
	List<Advisor>,即specificInterceptors 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;
}

AbstractAutoProxyCreator#createProxy

/**
 * Create an AOP proxy for the given bean.
 * 为指定 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 proxyFactory = new ProxyFactory();
 	proxyFactory.copyFrom(this);
 	// 根据一些情况判断是否要设置proxyTargetClass=true
 	if (!proxyFactory.isProxyTargetClass()) {
     
 		if (shouldProxyTargetClass(beanClass, beanName)) {
     
 			proxyFactory.setProxyTargetClass(true);
 		}
 		else {
     
 			evaluateProxyInterfaces(beanClass, proxyFactory);
 		}
 	}
 	// 把指定和通用拦截对象合并, 并都适配成Advisor
 	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

public class ProxyFactory extends ProxyCreatorSupport {
     
	public Object getProxy(ClassLoader classLoader) {
     
 	// 用ProxyFactory创建AopProxy, 然后用AopProxy创建Proxy, 所以这里重要的是看获取的AopProxy
 	// 对象是什么,
 	// 然后进去看怎么创建动态代理, 提供了两种:jdk proxy, cglib
 	return createAopProxy().getProxy(classLoader);
 	} 
}

public class ProxyCreatorSupport extends AdvisedSupport {
     
 	private AopProxyFactory aopProxyFactory;
 
 	public ProxyCreatorSupport() {
     
 	this.aopProxyFactory = new DefaultAopProxyFactory();
}
 
	protected final synchronized AopProxy createAopProxy() {
     
 		if (!this.active) {
     
 			activate();
 		}
 		//先获取创建AopProxy的工厂, 再由此创建AopProxy
 		return getAopProxyFactory().createAopProxy(this);
 	}
 
 	public AopProxyFactory getAopProxyFactory() {
     
 	return this.aopProxyFactory;
 	} 
}

流程就是用AopProxyFactory创建AopProxy, 再用AopProxy创建代理对象,这里的AopProxyFactory默认是DefaultAopProxyFactory,看他的createAopProxy方法

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
     

 	@Override
 	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()) {
     
 				return new JdkDynamicAopProxy(config);
 			}
 			return new ObjenesisCglibAopProxy(config);
 		} else {
     
 	return new JdkDynamicAopProxy(config);
 	}
}

/**
 * Determine whether the supplied {@link AdvisedSupport} has only the
 * {@link org.springframework.aop.SpringProxy} interface specified (or no
 * proxy interfaces specified at all).
 */
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
     
 	Class<?>[] interfaces = config.getProxiedInterfaces();
 	return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));
 	} 
}

这里决定创建代理对象是用JDK Proxy,还是用 Cglib 了,最简单的从使用方面使用来说:设置proxyTargetClass=true强制使用Cglib 代理,什么参数都不设并且对象类实现了接口则默认用JDK 代理,如果没有实现接口则也必须用Cglib

ProxyFactory#getProxy(java.lang.ClassLoader)

------ CglibAopProxy#getProxy(java.lang.ClassLoader)

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
     
 	if (logger.isTraceEnabled()) {
     
 		logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
 	}
 	
 	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);
 
 		// 配置 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 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);
 		
 		// 生成代理类,并且创建⼀个代理类的实例
 		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 anon-visible class",ex);
 	}
 	catch (Throwable ex) {
     
 	// TargetSource.getTarget() failed
 	throw new AopConfigException("Unexpected AOP exception", ex);
 	}
}

AOP源码分析类方法调用关系

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#i
nitializeBean

调用

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#a
pplyBeanPostProcessorsAfterInitialization

调用

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProce
ssAfterInitialization(后置处理器AbstractAutoProxyCreator完成bean代理对象创建)

调用

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNec
essary

调用

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createPro
xy (在这一步把委托对象的aop增强和通用拦截进行合并,最终给代理对象)

调用

org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy

调用

org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)

如果你需要这份完整版的《Spring高级源码笔记》,只需你多多支持我这篇文章。

多多支持,即可免费获取资料——三连之后(承诺:100%免费)

快速入手通道:添加助理VX:C18173184271,备注一下CSDN+工作年限! 免费获取!诚意满满!!!

你可能感兴趣的:(java,spring,aop,bean,spring,boot)