一、简介
Spring Aop模块采用了代理(Proxy)机制来实现AOP功能,在运行过程中aop框架大致可以分成三个阶段:创建代理、计算拦截器链、处理调用。
在“创建代理”阶段,Spring AOP可以根据目标类的实现或设置采用JDK自动代理或CGLIB来创建目标对象的代理;对于静态的Pointcut,框架在目标方法第一次调用时将计算应用于该方法之上的“拦截器链”;在方法调用时,框架将依次调用拦截器并最终执行方法的调用。
二、创建代理
ProxyFactoryBean是Spring AOP内置的工厂类,它能配置为spring容器中的bean,并为目标类创建代理:
public class ProxyFactoryBean extends AdvisedSupport
implements ... {
public Object getObject() throws BeansException {
// 初始化advisor列表
initializeAdvisorChain();
if (isSingleton()) { // 单件代理
return getSingletonInstance();
}
else {
...
return newPrototypeInstance();
}
}
...
}
在initializeAdvisorChain()方法中,Spring AOP将初始化ProxyFactoryBean配置中的Advisor:
public class ProxyFactoryBean extends AdvisedSupport
implements ... {
private synchronized void initializeAdvisorChain() throws ... {
...
// interceptorNames是ProxyFactoryBean在配置时设定的拦截器列表
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
...
for (int i = 0; i < this.interceptorNames.length; i++) {
String name = this.interceptorNames[i];
if (name.endsWith(GLOBAL_SUFFIX)) {
...
} else {
Object advice = null;
// 若代理和拦截器都是单件
if (this.singleton || this.beanFactory.isSingleton(this.interceptorNames[i])) {
// 从Spring Ioc容器中寻找
advice = this.beanFactory.getBean(this.interceptorNames[i]);
}
else { // 处理prototype的情形
...
}
// 将advice加入拦截器列表
addAdvisorOnChainCreation(advice, this.interceptorNames[i]);
}
}
}
this.advisorChainInitialized = true;
}
...
}
拦截器链初始化完成之后将创建代理:
public class ProxyFactoryBean extends AdvisedSupport
implements ... {
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
this.targetSource = freshTargetSource();
if (...) { //自动探测目标对象实现的接口
// Rely on AOP infrastructure to tell us what interfaces to proxy.
setInterfaces(ClassUtils.getAllInterfacesForClass(this.targetSource.getTargetClass()));
}
...
this.singletonInstance = getProxy(createAopProxy());
...
}
return this.singletonInstance;
}
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.beanClassLoader);
}
...
}
createAopProxy()方法来自ProxyFactoryBean的父类AdvisedSupport, 该方法将根据环境创建一个JDK或CGLIB代理
public class AdvisedSupport extends ProxyConfig implements Advised {
protected synchronized AopProxy createAopProxy() {
if (!this.isActive) {
activate();
}
// 使用AopProxyFactory来创建AopProxy
// 默认的factory是DefaultAopProxyFactory
return getAopProxyFactory().createAopProxy(this);
}
...
}
public class DefaultAopProxyFactory implements AopProxyFactory {
public AopProxy createAopProxy(AdvisedSupport advisedSupport) throws AopConfigException {
if (advisedSupport.isOptimize() || advisedSupport.isProxyTargetClass() ||
advisedSupport.getProxiedInterfaces().length == 0) { // 使用CGLIB创建proxy
...
return CglibProxyFactory.createCglibProxy(advisedSupport);
}
else {
return new JdkDynamicAopProxy(advisedSupport);
}
}
...
}
其中JdkDynamicAopProxy类使用JDK动态代理来创建AOP功能:
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
public Object getProxy(ClassLoader classLoader) {
...
// 得到要代理的接口,系统自动追加Advised接口
Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
// 检查equals()和hashCode()方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 使用java.lang.reflect.Proxy来创建JDK代理
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
...
}
调用的UML图: