spring bean 的增强,具体体现在 Aspect 切面拦截 与 Transactional 事务上。
在 spring bean的加载 中,bean 初始化之后会调用 applyBeanPostProcessorsAfterInitialization() 方法,该方法即可以 bean 进行增强,通过调用 BeanPostProcessors 的 postProcessAfterInitialization() 方法。
当 Application 开启了切面代理(@EnableAspectJAutoProxy)或者事务管理(@EnableTransactionManagement) 的时候,会在系统内注册一个 AutoProxyCreator ,这是一个 processer,看下它在 bean 初始化后增强的具体代码。
AbstractAutoProxyCreator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { 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; } }
|
getAdvicesAndAdvisorsForBean 决定了 bean 是否需要增强,如果需要,会将这个 bean 的 Advices 和 Advisors 都拿出来,用来创建代理对象。
Advisors 就是容器中存在的 AspectBean , Advices 就是 AspectBean 中的 before 和 after 方法。
createProxy 方法内通过调用一个 ProxyFactory 来获取代理对象,ProxyFactory 会通过 ProxyCreatorSupport 来创建一个默认的 DefaultAopProxyFactory。
DefaultAopProxyFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @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() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
|
代理工厂会根据配置与目标对象的类型,选择用JDK动态代理,还是CGLIB的代理。
之前在整理 Spring AOP 时,比较了 jdk 与 cglib 的区别。还有那张代理对象创建流程图也有,这里在贴一下。

Title: Spring Bean 增强
Author: Jiandong
Date: 2019-07-06
Last Update: 2025-02-23
Blog Link: https://mjd507.github.io/2019/07/06/Spring-Bean-Enhance/
Copyright Declaration: Please refer carefully, most of the content I have not fully mastered.