a. 实现方式:cglib 和 jdk自带的Proxy实现

b. 策略:

1)如果是有接口声明的类进行AOP 时,spring调用的是Java.lang.reflection.Proxy 类来做处理

2)如果是没有接口声明的类时, spring通过cglib包和内部类来实现

c.配置:

<aop:aspectj-autoproxy proxy-target-class="true" />配置了这句话的话就会强制使用cglib代理。 默认就是false

spring动态代理策略

// Spring source
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        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)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

    /**
     * Determine whether the supplied {@link AdvisedSupport} has only the
     * {@link org.springframework.aop.SpringProxy} interface specified
     * (or no proxy interfaces specified at all).
     */
    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class<?>[] ifcs = config.getProxiedInterfaces();
        return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
    }

}

FAQ

  1. Spring AOP无法代理private方法?

jdk是代理接口,私有方法必然不会存在在接口里,所以就不会被拦截到;cglib是子类,private的方法照样不会出现在子类里,也不能被拦截,private方法在Spring使用纯Spring AOP都是无法被拦截的 因为子类无法覆盖(只能拦截public/protected/包);包级别能被拦截的原因是,如果子类和父类在同一个包中是能覆盖的;;如果想要实现拦截private方法的代理,可以使用原生AspectJ静态织入

results matching ""

    No results matching ""