在上篇文章SpringAop源码分析(基于注解)二:筛选通知器中,咱们对AOP中通知的建立和筛选过程进行了分析,本章咱们一块儿来看看,AOP是怎么建立代理对象的。java
咱们先回到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代码:ide
//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 的某些方法先后。源码分析
看代码:post
//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());
}
复制代码
这里咱们主要看下核心逻辑:优化
这里的 isProxyTargetClass() 其实就是咱们前面用的注解@EnableAspectJAutoProxy
的属性之一,当其为true时,强制使用CGLIB代理。ui
下面咱们接着看建立代理的代码:this
//ProxyFactory.java
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
复制代码
这段方法有两个方法调用:lua
咱们先来看下createAopProxy():spa
//DefaultAopProxyFactory.java
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//if中的3个条件
//一、 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)) {
//建立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 方法建立代理对象。