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