文前说明
作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。
本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。
1. 概述
- Spring 为目标 bean 筛选到合适的通知器(可查看 【Spring 笔记】AOP 通知筛选相关整理 了解)后,再通过 创建代理对象 的方式将 Advisor(通知器)所持有的 Advice(通知)织入到 bean 的某些方法前后。
proxy-target-class
- 在 Spring AOP 配置中,proxy-target-class 属性可以影响 Spring 创建代理对象的类型。
<!-- spring.xml -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<aop:config proxy-target-class="true">
<aop:aspect id="xxx" ref="xxxx">
</aop:aspect>
</aop:config>
- 默认情况下 proxy-target-class 属性为 false。
- 当目标 bean 实现了接口时,Spring 会基于 JDK 动态代理 为目标 bean 创建代理对象。
- 若未实现任何接口,Spring 则会通过 CGLIB 创建代理对象。
- 当 proxy-target-class 属性设为 true 时,则会强制 Spring 通过 CGLIB 的方式创建代理对象,即使目标 bean 实现了接口。
- 详细可以查看 Java 动态代理实现 了解。
optimize
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 只为后缀为"impl"的bean生产代理 -->
<property name="beanNames" value="*impl"></property>
<!-- 增强 -->
<property name="interceptorNames" value="aServiceAdvisor"></property>
<!-- 是否对代理策略进行优化 -->
<property name="optimize" value="true"></property>
</bean>
- 是否对代理策略进行优化,默认情况下 optimize 值为 false。
2. 原理
// AbstractAutoProxyCreator.java
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Override
// bean 初始化后置处理方法
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
// 如果需要,为 bean 生成代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
......
/*
* 若 specificInterceptors != null,即 specificInterceptors != DO_NOT_PROXY,
* 则为 bean 生成代理对象,否则直接返回 bean
*/
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 1. 创建代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
/*
* 返回代理对象,此时 IOC 容器输入 bean,得到 proxy。此时,
* beanName 对应的 bean 是代理对象,而非原始的 bean
*/
return proxy;
}
......
}
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);
/*
* 默认配置下,或用户显式配置 proxy-target-class = "false" 时,
* 这里的 proxyFactory.isProxyTargetClass() 也为 false
*/
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
/*
* 检测 beanClass 是否实现了接口,若未实现,则将
* proxyFactory 的成员变量 proxyTargetClass 设为 true
*/
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// specificInterceptors 中若包含有 Advice,此处将 Advice 转为 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.java
public Object getProxy(ClassLoader classLoader) {
// 先创建 AopProxy 实现类对象,然后再调用 getProxy 为目标 bean 创建代理对象
return createAopProxy().getProxy(classLoader);
}
// ProxyCreatorSupport.java
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
this.activate();
}
// 返回 AopProxy
return this.getAopProxyFactory().createAopProxy(this);
}
- 步骤 1 中,如果通知器数组不为空,则为 bean 生成代理对象。
AopProxy
- 为目标 bean 创建代理对象前,需要先创建
AopProxy
对象。
// AopProxy.java
public interface AopProxy {
/** 创建代理对象 */
Object getProxy();
Object getProxy(ClassLoader classLoader);
}
- Spring 中两个类实现了
AopProxy
。
DefaultAopProxyFactory
- 由
getAopProxyFactory()
方法获取DefaultAopProxyFactory
工程类。
// DefaultAopProxyFactory.java
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
/*
* config.isOptimize() 是否对代理策略进行优化
* config.isProxyTargetClass() 检测 proxyTargetClass 的值
* hasNoUserSuppliedProxyInterfaces(config) 目标 bean 是否实现了接口
*/
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);
}
// 创建 CGLIB 代理,ObjenesisCglibAopProxy 继承自 CglibAopProxy
return new ObjenesisCglibAopProxy(config);
}
else {
// 创建 JDK 动态代理
return new JdkDynamicAopProxy(config);
}
}
}
- Spring 根据 bean 是否实现接口,以及一些配置决定使用
AopProxy
何种实现类为目标 bean 创建代理对象。
getProxy
- 以
JdkDynamicAopProxy
为例,为目标 bean 创建代理对象。
// JdkDynamicAopProxy.java
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 调用 newProxyInstance 创建代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
网友评论