34--SpringAop创建代理

版权声明:如有转载,请标明出处,谢谢合作! 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里执行了两个操作:

  1. 提取自定义拦截器/增强,例如注释中的通过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属性。

  1. 包装所有的拦截器/增强,将其统一转换为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动态代理的调用过程。

猜你喜欢

转载自blog.csdn.net/lyc_liyanchao/article/details/83792064