AOP的BeanDefinition加载后,Spring提供了自动代理机制,让容器自动根据目标bean生成AOP代理bean,本文讲述具体如何实现。
基本机制
Spring的启动过程中,在bean实例化前后、初始化前后均提供了外部介入处理机制(详见“一起学SF框架系列5.3-spring-Beans-bean与Spring容器的交互方式”)。AOP正是通过其中BeanPostProcessor类来自动完成这项工作。下面是自动代理创建类关系图:
从上图可看出,自动创建代理类均继承于AbstractAutoProxyCreator,而AbstractAutoProxyCreator实现了接口SmartInstantiationAwareBeanPostProcessor,该接口继承于BeanPostProcessor。
启动入口
在bean创建过程中,自动代理创建类可以有四个介入时机:
1、实例化前(SmartInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation)
2、实例化后(SmartInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation)
3、初始化前(BeanPostProcessor.postProcessBeforeInitialization)
4、初始化后(BeanPostProcessor.postProcessAfterInitialization)
实际代码跟踪,AbstractAutoProxyCreator实现了如下两个接口:
实例化前:postProcessBeforeInstantiation
初始化后:postProcessAfterInitialization
跟踪启动过程,真正入口在AbstractAutoProxyCreator.postProcessAfterInitialization。这更符合实际:因为应用开发时,目标对象bean是不需要知道AOP任何内容的,有AOP能正常工作,无AOP也能正常工作,因此目标对象bean在初始化后再转换成代理对象就更恰当。
源码跟踪
AbstractAutoProxyCreator.postProcessAfterInitialization(@Nullable Object bean, String beanName)
创建bean的代理对象。
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 为给定的bean类和bean名称构建一个缓存键
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// bean没有对应的代理,则创建代理
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
AbstractAutoProxyCreator.wrapIfNecessary(Object bean, String beanName, Object cacheKey)
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果目标bean已存在(在bean实例化前创建的),直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 目标bean不是advisedBean,直接返回
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 如果是基础类(是不能被代理的)或者 应该跳过的bean(“跳过”意思是给定的bean不应被此后处理器进行自动代理),直接返回
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
/* 创建代理类 */
// 获取所有适用于当前Bean的Advisors 注1
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
/* 存在适用于当前Bean的Advisors */
if (specificInterceptors != DO_NOT_PROXY) {
// 标记该bean是被代理类的bean
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理bean 注2
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 标记bean的代理类型
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 标记该bean非被代理类的bean
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
注1/ 注2方法过程均比较复杂,见下面专门章节。
获取所有适用于当前Bean的Advisors
AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource)
// 过渡类
@Override
@Nullable
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();
}
// 查找适用于bean所有符合条件的Advisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 查找BeanFactory所有Advisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 找适用于bean的Advisors
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
// 查找BeanFactory所有Advisors
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
// 返回所有Advisors
return this.advisorRetrievalHelper.findAdvisorBeans();
}
// 找适用于bean的Advisors
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
// 设置代理创建容器当前处理的beanName
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
// 适配查找
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
// 清理代理创建容器当前处理的beanName
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()
// 查找BeanFactory所有Advisors
public List<Advisor> findAdvisorBeans() {
// 获取所有已缓存的AdvisorBeanNames
String[] advisorNames = this.cachedAdvisorBeanNames;
/* 缓存没有 */
if (advisorNames == null) {
// 在beanFactory中查找所有Advisor类
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
// 结果放到缓存
this.cachedAdvisorBeanNames = advisorNames;
}
// 不存在Advisor类
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
/* 逐一判断每个advisor是否适合当前bean */
for (String name : advisorNames) {
if (isEligibleBean(name)) { // isEligibleBean返回的总是true
if (this.beanFactory.isCurrentlyInCreation(name)) {
// 当前bean正被创建中,就跳过
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
// 获取每个advisor的bean实例(当成普通bean获取实例),加入到集合中
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
// 如果异常是因为bean正在创建中引起的,则continue处理下一个advisor
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
注意:advisor类都是prototype类型,因此每次获取都需要创建
AopUtils.findAdvisorsThatCanApply(List candidateAdvisors, Class<?> clazz)
从Advisors侯选择中选择适合beanClass的Advisors
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
// 后选择为空
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
// 选择结果集合
List<Advisor> eligibleAdvisors = new ArrayList<>();
/* 处理引介增强 declare-parents*/
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// 上一步已处理
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
// advisor是否适合class --过渡类
public static boolean canApply(Advisor advisor, Class<?> targetClass) {
return canApply(advisor, targetClass, false);
}
// advisor是否适合class
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
// 引介增强器判断是否合适(同切点判断方式不一样)
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor pca) {
// 切点判断是否合适
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// 没有切点的话,假定是合适的 (why?)
return true;
}
}
// 用切点判断advisor是否适合class
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;
}
// 判断方法是否匹配
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
// 判断是否引介增强匹配 注1
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
/* 对目标类和所有实现的接口类的方法进行匹配判断 */
Set<Class<?>> classes = new LinkedHashSet<>();
// 如果目标类不是代理类,加入待处理类
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
// 获取目标类实现的所有接口(包括由祖先类实现的)
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
// 逐一对目标类或实现接口类的方法进行切点匹配判断
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
注1:切点匹配主要是通过表达式同类或方法进行匹配判断,不再进一步跟踪。相关类主要是AspectJExpressionPointcut,相关类图如下:
创建代理bean
AbstractAutoProxyCreator.createProxyClass(Class<?> beanClass, @Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource)
创建代理bean
//过渡类
private Class<?> createProxyClass(Class<?> beanClass, @Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource) {
return (Class<?>) buildProxy(beanClass, beanName, specificInterceptors, targetSource, true);
}
//创建代理bean
private Object buildProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource, boolean classOnly) {
// 在ConfigurableListableBeanFactory中设置目标类为原始类
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 获取当前类的ProxyConfig属性 (两者都祖先类都有ProxyConfig)
proxyFactory.copyFrom(this);
// 判断当前代理工厂(来自上一步的copy属性)是基于TargetClass代理还是基于接口代理
if (proxyFactory.isProxyTargetClass()) {
// 代理工厂是基于TargetClass代理
if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
// bean是处理类或lambdas类
for (Class<?> ifc : beanClass.getInterfaces()) {
// 把接口方法加入到代理工厂
proxyFactory.addInterface(ifc);
}
}
}
else {
// 代理工厂是基于接口代理
// 确定bean是目标类而不是接口
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// bean的接口加到代理工厂
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 封装所有Advisors
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 把Advisors加到代理工行
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 如果bean类不是用重写类类加载器加载,就使用原始类加载器
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
// 创建代理类返回
return (classOnly ? proxyFactory.getProxyClass(classLoader) : proxyFactory.getProxy(classLoader));
}
ProxyFactory.getProxyClass(@Nullable ClassLoader classLoader)
public Object getProxyClass(@Nullable ClassLoader classLoader) {
// createAopProxy()创建AOP代理器,再由代理器生成代理类(getProxyClass(classLoader))
return createAopProxy().getProxyClass(classLoader);
}
// createAopProxy()-创建AOP代理器的实现过程
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
// createAopProxy(this)-创建AOP代理器的实现过程 注1
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// optimize 默认false,为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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
// 接口类、代理目标类或Lambda类用JDK的动态代理器
return new JdkDynamicAopProxy(config);
}
// 用CGLIB动态代理器
return new ObjenesisCglibAopProxy(config);
}
else {
// 接口类、代理目标类或Lambda类用JDK的动态代理器
return new JdkDynamicAopProxy(config);
}
}
注1:JDK的动态代理器或CGLIB动态代理器的类图关系:
JDK动态代理器-JdkDynamicAopProxy生成代理类
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
/* 下面方法来自:java.lang.reflect.Proxy (均是jdk本身的,同spring无关)*/
/** 新生成指定接口的代理实例,该实例将方法调用分派给指定的调用处理程序
@param loader 定义代理类的类加载器
@param interfaces 要实现的代理类的接口列表
@param h InvocationHandler是方法调用处理器,就是在invoke方法时进行代理封装
*/
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) {
// h 不能为空
Objects.requireNonNull(h);
// 获取调用本方法的方法的调用类
@SuppressWarnings("removal")
final Class<?> caller = System.getSecurityManager() == null
? null
: Reflection.getCallerClass();
//查找或生成指定的代理类的构造器
Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
// 构建代理类新实例并返回
return newProxyInstance(caller, cons, h);
}
//查找或生成指定的代理类的构造器
private static Constructor<?> getProxyConstructor(Class<?> caller,
ClassLoader loader,
Class<?>... interfaces)
{
// optimization for single interface
// 只有一个接口需做代理
if (interfaces.length == 1) {
Class<?> intf = interfaces[0];
if (caller != null) {
// 检查是否允许被代理
checkProxyAccess(caller, loader, intf);
}
return proxyCache.sub(intf).computeIfAbsent(
loader,
(ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
);
} else {
// 多个接口需做代理
//克隆拿到接口
final Class<?>[] intfsArray = interfaces.clone();
if (caller != null) {
checkProxyAccess(caller, loader, intfsArray);
}
final List<Class<?>> intfs = Arrays.asList(intfsArray);
return proxyCache.sub(intfs).computeIfAbsent(
loader,
(ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
);
}
}
// 生成新实例
private static Object newProxyInstance(Class<?> caller,
Constructor<?> cons,
InvocationHandler h) {
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (caller != null) {
checkNewProxyPermission(caller, cons.getDeclaringClass());
}
// 用构建器生成新实例
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException | InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
}
}
CGLIB代理器-CglibAopProxy生成代理类
// 过渡类
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
return buildProxy(classLoader, false);
}
private Object buildProxy(@Nullable ClassLoader classLoader, boolean classOnly) {
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;
// 类是CGLIB类(beanName字含有“$$“,注意同java嵌套类区别(含有"$");针对引入增强
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
// 取上级类
proxySuperClass = rootClass.getSuperclass();
// 获取所有接口加入到advisor
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封装的增强类,支持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.setAttemptLoad(true);
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 (classOnly ? createProxyClass(enhancer) : 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创建目标类代理实例
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}