版权声明:如有转载,请标明出处,谢谢合作! https://blog.csdn.net/lyc_liyanchao/article/details/83792064
上一节已经分析了AOP获取增强的过程,接下来介绍AOP创建代理的过程。
1.创建代理的准备工作
/**
* 为给定的bean创建代理
* Create an AOP proxy for the given bean.
* @param beanClass the class of the bean
* @param beanName the name of the bean
* @param specificInterceptors the set of interceptors that is
* specific to this bean (may be empty, but not null)
* @param targetSource the TargetSource for the proxy,
* already pre-configured to access the bean
* @return the AOP proxy for the bean
* @see #buildAdvisors
*/
protected Object createProxy(Class<?> beanClass,
@Nullable String beanName,
@Nullable Object[] specificInterceptors,
TargetSource targetSource) {
// 1、当前beanFactory是ConfigurableListableBeanFactory类型,则尝试暴露当前bean的target class
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 2、创建ProxyFactory并配置
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 是否直接代理目标类以及接口
if (!proxyFactory.isProxyTargetClass()) {
// 确定给定bean是否应该用它的目标类而不是接口进行代理
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
// 检查给定bean类上的接口,如果合适的话,将它们应用到ProxyFactory。即添加代理接口
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 3、确定给定bean的advisors,包括特定的拦截器和公共拦截器,是否适配Advisor接口。
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 设置增强
proxyFactory.addAdvisors(advisors);
// 设置代理目标
proxyFactory.setTargetSource(targetSource);
// 定制proxyFactory(空的模板方法,可在子类中自己定制)
customizeProxyFactory(proxyFactory);
// 锁定proxyFactory
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 4、创建代理
return proxyFactory.getProxy(getProxyClassLoader());
}
前面已经介绍了ProxyFactory的使用,这里我们主要分析第三步、第四步。
- buildAdvisors 分析
前面已经介绍了增强的获取,那么为什么在这里还要再次buildAdvisors呢?打开buildAdvisors的源码:
/**
* 确定给定bean的advisors,包括特定的拦截器和公共拦截器。
* Determine the advisors for the given bean, including the specific interceptors
* as well as the common interceptor, all adapted to the Advisor interface.
* @param beanName the name of the bean
* @param specificInterceptors the set of interceptors that is
* specific to this bean (may be empty, but not null)
* @return the list of Advisors for the given bean
*/
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
// 解析自定义的拦截器/增强,并将其转换为Advisor
/**
* 例如:
* <bean id="dog" class="com.lyc.cn.v2.day07.Dog"/>
* <bean id="beforeAdvice" class="com.lyc.cn.v2.day07.advisor.MyBeforeAdvice"/>
* <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
* // 匹配的bean名称
* <property name="beanNames">
* <value>dog*</value>
* </property>
* // 拦截器/增强
* <property name="interceptorNames">
* <list>
* <value>beforeAdvice</value>
* </list>
* </property>
* </bean>
*/
Advisor[] commonInterceptors = resolveInterceptorNames();
// 将解析的自定义拦截器和指定的拦截器加入到allInterceptors集合
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
// 转换advisor
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
buildAdvisors里执行了两个操作:
- 提取自定义拦截器/增强,例如注释中的通过BeanNameAutoProxyCreator配置的拦截器
/**
* 解析拦截器、增强
* Resolves the specified interceptor names to Advisor objects.
* @see #setInterceptorNames
*/
private Advisor[] resolveInterceptorNames() {
BeanFactory bf = this.beanFactory;
ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null);
List<Advisor> advisors = new ArrayList<>();
// 循环interceptorNames属性,获取对应的beanName实例,并包装成Advisor对象
for (String beanName : this.interceptorNames) {
if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
Object next = bf.getBean(beanName);
advisors.add(this.advisorAdapterRegistry.wrap(next));
}
}
return advisors.toArray(new Advisor[0]);
}
AbstractAutoProxyCreator抽象类为interceptorNames属性提供了set方法,而BeanNameAutoProxyCreator实现了AbstractAutoProxyCreator抽象类,所以通过配置BeanNameAutoProxyCreator,可以自动注入interceptorNames属性。
- 包装所有的拦截器/增强,将其统一转换为Advisor对象
/**
* 包装增强、增强器等
* @param adviceObject
* @return
* @throws UnknownAdviceTypeException
*/
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
// 1、封装Advisor类型
// 如果要封装的对象本身就是Advisor类型,那么直接返回即可
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
// 如果要封装的对象即不是Advisor类型也不是Advice类型,那么抛出异常
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
// 2、封装Advice类型
Advice advice = (Advice) adviceObject;
// 如果advice是MethodInterceptor类型,则使用DefaultPointcutAdvisor封装
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
// 如果advice不是MethodInterceptor类型,存在适配器,且适配器支持该advice类型,则使用DefaultPointcutAdvisor封装
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
// 3、未能正常处理,抛出异常
throw new UnknownAdviceTypeException(advice);
}
包装的过程比较简单,对adviceObject的类型判断并返回对应的包装类即可,如果adviceObject即不是Advisor类型,也不是Advice类型,则抛出异常。
2.创建代理
- 判断创建JDK或CGLIB动态代理
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
/**
* 创建代理
* 1、config.isOptimize():判断通过CGLIB创建的代理是否使用了优化策略
* 2、config.isProxyTargetClass():是否配置了proxy-target-class为true
* 3、hasNoUserSuppliedProxyInterfaces(config):是否存在代理接口
* 4、targetClass.isInterface()-->目标类是否为接口
* 5、Proxy.isProxyClass-->如果targetClass类是代理类,则返回true,否则返回false。
*
* @param config the AOP configuration in the form of an
* AdvisedSupport object
* @return
* @throws AopConfigException
*/
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 1、判断是否需要创建CGLIB动态代理
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)) {
// 创建jdk动态代理
return new JdkDynamicAopProxy(config);
}
// 创建CGLIB动态代理
return new ObjenesisCglibAopProxy(config);
}
// 2、默认创建JDK动态代理
else {
return new JdkDynamicAopProxy(config);
}
}
看到这里,终于看见了JDK和CGLIB动态代理的创建。关于两者创建的条件判断,以及每个条件的含义,都已经写在注释里了。但是在new ObjenesisCglibAopProxy(config);
和JdkDynamicAopProxy(config);
并没有做实质的操作,只是创建了ObjenesisCglibAopProxy和JdkDynamicAopProxy对象实例而已。返回真正代理的是getProxy方法。接下来分析JDK和CGLIB两种代理的获取过程。
- 获取JDK动态代理
/**
* 创建JDK动态代理
* @param classLoader the class loader to create the proxy with
* (or {@code null} for the low-level proxy facility's default)
* @return
*/
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
logger.info("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
// 确定用于给定AOP配置的代理的完整接口集。
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 判断被代理接口有没有重写equals和hashCode方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 为接口创建代理
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
- 获取CGLIB动态代理
/**
* 创建CGLIB动态代理
* @param classLoader the class loader to create the proxy with
* (or {@code null} for the low-level proxy facility's default)
* @return
*/
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
logger.info("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
try {
Class<?> rootClass = this.advised.getTargetClass();
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// 新建并配置Enhancer
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
// 生成代理类并创建代理实例
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
到这里就完成了代理的自动创建过程了。接下来分析JDK和CGLIB动态代理的调用过程。