得到增强器后,开始着手于创建代理对象,那么首先创建代理工厂。
主要在 AbstractAutoProxyCreator#createProxy,简单工厂模式。
能产生两类对象:CglibAopProxy、JdkDynamicAopProxy。
创建代理工厂,准备创建代理对象所需要的各种资源,具体流程和源码如下:
- 公开需要被代理的对象,在该对象的 BeanDefinition 写入属性 org.springframework.aop.framework.autoproxy.AutoProxyUtils.originalTargetClass-targetClass
- 新建代理工厂:ProxyFactory,并从当前对象 (AnnotationAwareAspectJAutoProxyCreator,具体看使用注解aop还是xml的aop) 拷贝属性;
- 判断
proxy-target-class
属性(TRUE表示强制使用CGLIB代理对象所有的方法):- true
- 判断当前对象是否是JDK代理生成的,如果是把其所有的接口加入ProxyFactory
- false
- 判断是否应该直接代理目标对象,满足下面俩条件的话:就设置 proxyTargetClass=true
- 条件1:beanFactory 是 ConfigurableListableBeanFactory 的实例;
- 条件2:目标bean在IOC中存在,并且其定义中包含上面1中暴露的属性;
- 上面不满足,那么判断是否应该代理目标对象的接口,如果没有符合条件的接口那么设置 proxyTargetClass=true;如果有符合条件的接口,那么把其所有的接口加入ProxyFactory。这里符合条件的接口需要满足三个条件:
- 不容容器内部的接口;
- 不是内部语言接口,比如 xx.cglib.proxy.Factory、xx.bytebuddy.MockAccess;
- 接口中必须有方法。
- 判断是否应该直接代理目标对象,满足下面俩条件的话:就设置 proxyTargetClass=true
- true
- 第3步有很多的判断,主要是为了设置 proxyTargetClass 属性。接下来把并增强的方法包装成 Advisor 数组放到 ProxyFactory 中;和我们目标代理对象也放到 ProxyFactory 中;
- 留给用户扩展点 customizeProxyFactory(proxyFactory);
- 是否需要冻结配置 proxyFactory.setFrozen(this.freezeProxy);
- AbstractAdvisorAutoProxyCreator 将 advisorsPreFiltered() 重写为true;
- 工厂准备完毕,下一步创建 AOP代理对象 proxyFactory.getProxy(getProxyClassLoader());
源码
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// 如果beanFactory是ConfigurableListableBeanFactory的实例
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
// 公开指定需要代理的对象
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 新建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 判断是否配置了 <aop:aspectj-autoproxy proxy-target-class="true"/>,表示使用CGLIB实现AOP。默认false
if (proxyFactory.isProxyTargetClass()) {
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
// 判断当前对象是否是JDK代理生成的
// 当Proxy.newProxyInstance方法动态getProxyClass生成为代理类时,返回 true。
if (Proxy.isProxyClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
} else {
// No proxyTargetClass flag enforced, let's apply our default checks...
// 判断是否应该代理该对象
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
// 评估是否应该代理该对象的接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 得到增强的拦截方法
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
// 扩展点
customizeProxyFactory(proxyFactory);
// 冻结配置
proxyFactory.setFrozen(this.freezeProxy);
// 被子类重写为true
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 准工作结束,开始创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
shouldProxyTargetClass
首先判断下 beanFactory 的类型,然后需要判断下 beanDefination了里面的属性值。
protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName) {
return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
}
进入 AutoProxyUtils 的方法 shouldProxyTargetClass
判断bean存在,及其其定义中是否包含属性。
public static boolean shouldProxyTargetClass(
ConfigurableListableBeanFactory beanFactory, @Nullable String beanName) {
if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
// 判断BeanDefinition中是否有如下属性
// org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass
return Boolean.TRUE.equals(bd.getAttribute(PRESERVE_TARGET_CLASS_ATTRIBUTE));
}
return false;
}
evaluateProxyInterfaces
判断能否使用 jdk 动态代理。能的话拿到接口,不能的话设置 proxyFactory.setProxyTargetClass(true);
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
// 返回目标对象所有的接口
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
// 是否有符合的代理接口
boolean hasReasonableProxyInterface = false;
for (Class<?> ifc : targetInterfaces) {
// isConfigurationCallbackInterface(ifc) 是否为容器的回调接口
// isInternalLanguageInterface(ifc) 是否为内部语言接口
// 接口中必须有方法
if (!isConfigurationCallbackInterface(ifc)
&& !isInternalLanguageInterface(ifc)
&& ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;
break;
}
}
if (hasReasonableProxyInterface) {
// Must allow for introductions; can't just set interfaces to the target's interfaces only.
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
} else {
proxyFactory.setProxyTargetClass(true);
}
}