前面分析了spring aop的实现原理。为了突出整个流程的清晰,其中有些细节部分没有详细分析。
现在就分析一下aop生成代理对象的细节。言乘上文,spring aop 生成代理对象是在
AbstractAutoProxyCreator的如下方法中:
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
proxyFactory.copyFrom(this);
if (!shouldProxyTargetClass(beanClass, beanName)) {
// Must allow for introductions; can't just set interfaces to
// the target's interfaces only.
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
for (Class<?> targetInterface : targetInterfaces) {
proxyFactory.addInterface(targetInterface);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(this.proxyClassLoader);
}
从上面可以看出,如果设置了proxyTargetClass,那么proxyFactory就不调用addInterface.
跟踪一下最后代码,最后实际调用了了DefaultAopProxyFactory的createAopProxy方法,代码如下:
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()) {
return new JdkDynamicAopProxy(config);
}
if (!cglibAvailable) {
throw new AopConfigException(
"Cannot proxy target class because CGLIB2 is not available. " +
"Add CGLIB to the class path or specify proxy interfaces.");
}
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
这段代码的意义很明确。如果设置了proxyTargetClass或者根本没有接口,那么就
使用CglibProxyFactory生成代理。否则使用JdkDynamicAopProxy。
这两种代理方式的实现细节在此不作分析。