在上篇文章SpringAop源码分析(基于注解)二:筛选通知器中,我们对AOP中通知的创建和筛选过程进行了分析,本章我们一起来看看,AOP是怎么创建代理对象的。
我们先回到Bean初始化之后,调用BeanPostProcessor后置处理器的地方。
//AbstractAutoProxyCreator.java
//在Bean初始化之后回调
@Override
public Object postProcessAfterInitialization(@Nullable 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;
}
wrapIfNecessary代码:
//AbstractAutoProxyCreator.java
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;
}
/*
* 如果是基础设施类(Pointcut、Advice、Advisor 等接口的实现类),或是应该跳过的类,
* 则不应该生成代理,此时直接返回 bean
*/
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
<1> // 返回匹配当前 bean 的所有的通知器 advisor、advice、interceptor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 核心!创建代理对象
<2> 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;
}
上篇文章我们主要分析的是<1>处代码,现在有了合适的通知器,我们要为当前Bean创建代理对象,把通知器(Advisor)所持有的通知(Advice)织入到 bean 的某些方法前后。
看代码:
//AbstractAutoProxyCreator.java
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 = new ProxyFactory();
proxyFactory.copyFrom(this);
//proxyTargetClass是 @EnableAspectJAutoProxy 的属性之一
//true -> 强制使用CGLIB代理
if (!proxyFactory.isProxyTargetClass()) {
//false
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
//检测 beanClass 是否实现了接口,若未实现,则将
//proxyFactory 的成员变量 proxyTargetClass 设为 true
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//封装proxyFactory
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
- 判断使用JDK还是CGLIB
- 封装ProxyFactory
- 创建并获取代理对象
这里的 isProxyTargetClass() 其实就是我们前面用的注解@EnableAspectJAutoProxy
的属性之一,当其为true时,强制使用CGLIB代理。
下面我们接着看创建代理的代码:
//ProxyFactory.java
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
这段方法有两个方法调用:
- createAopProxy()
创建 AopProxy 实现类对象 - getProxy(classLoader)
创建代理对象
我们先来看下createAopProxy():
//DefaultAopProxyFactory.java
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//if中的3个条件
//1、 config.isOptimize() - 是否需要优化
//2、 config.isProxyTargetClass() - 检测 proxyTargetClass 的值
//3、 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)) {
//创建JdkDynamicAopProxy
return new JdkDynamicAopProxy(config);
}
//创建CglibAopProxy
return new ObjenesisCglibAopProxy(config);
}
else {
//创建JdkDynamicAopProxy
return new JdkDynamicAopProxy(config);
}
}
最终调用的是DefaultAopProxyFactory#createAopProxy(...)
方法,通过这个方法创建AopProxy 的实现类,如: JdkDynamicAopProxy,然后根据这个实现类再创建代理对象。
我们以JdkDynamicAopProxy为例,看下getProxy(classLoader)
:
//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);
}
直接看代码最后一行,最终调用 Proxy.newProxyInstance 方法创建代理对象。