一、简介
AOP源码分析主要分为5个篇章:前面3篇已经讲了
1. 注册、实例化、初始化AnnotationAwareAspectJAutoProxyCreator
【十】Spring源码分析之AOP----注册、实例化、初始化AnnotationAwareAspectJAutoProxyCreator
2. 扫描容器中的切面,创建PointcutAdvisor对象
【十一】Spring源码分析之AOP----AnnotationAwareAspectJAutoProxyCreator扫描@Aspect,创建Advisor3.解析pointcut切点的表达式,看该目标bean与哪些Advisor匹配
【十二】Spring源码分析之AOP----匹配出作用于被代理类Advisor
4.Spring源码分析之AOP----生成代理对象。就是本篇。
5. 被代理类的方法一次调用流程。
本篇讲述:
AOP创建代理实例,包括cglib和JDK
方法调用栈:
入口:
AbstractAutoProxyCreator类的createProxy方法
源码:
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
// 暴露目标类
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 新建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 当前ProxyCreator在创建代理时将需要用到的字段赋值到ProxyFactory中去
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
//是否使用targetClass类,而不是接口来进行代理
if (shouldProxyTargetClass(beanClass, beanName)) {
// 使用目标类来代理,这基本上就是会用cglib代理了
proxyFactory.setProxyTargetClass(true);
}
else {
// 使用接口代理,会调用这个方法看到底使用哪个接口,如果找不到合适的接口还是会用目标类本身来代理
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 将该bean的所有Advisor以及拦截器统一封装成Advisor,并设置到proxyFactory中
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 往代理工厂中加入Advisor
proxyFactory.addAdvisors(advisors);
// 往代理工厂中加入目标类
proxyFactory.setTargetSource(targetSource);
// 定制代理工厂
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 从代理工厂中获取代理实例
return proxyFactory.getProxy(getProxyClassLoader());
}
做了7件事:
1.如果beanFactory是ConfigurableListableBeanFactory的类型,暴露目标类。
2.创建一个ProxyFactory,当前ProxyCreator在创建代理时将需要用到的字段赋值到ProxyFactory中去。
3.判断是否使用targetClass目标类本身来代理
4.将该bean的所有Advisor以及拦截器统一封装成Advisor,并设置到proxyFactory中。
5.往代理工厂中加入目标类
6.定制代理工厂
7.从代理工厂中获取代理实例
二、proxyFactory.getProxy方法
源码:
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
做了2件事:
1.创建AOP代理
2.获取代理实例
三、createAopProxy方法
源码:
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
追踪进getAopProxyFactory方法发现返回的就是一个DefaultAopProxyFactory类
调用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() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
做了1件事:基于接口的代理就new JdkDynamicAopProxy,没有接口的代理就new ObjenesisCglibAopProxy
这里我的目标类不是基于接口的,所以是new ObjenesisCglibAopProxy走得cglib代理。
四、 CglibAopProxy类的getProxy方法
由于这里是cglib代理,调用的是CglibAopProxy类的getProxy方法
源码:
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}
try {
//从advised 中获取目标对象
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
// 这里判断rootClass是否是Cglib代理所产生的类(内部判断rootClass的className是否包含$$)
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.
// 验证proxySuperClass中的是否有final方法(有则打印出来警告信息,该方法不能被代理)
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
// 创建配置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
// 设置回调过滤ClassFilter和回调类型
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
// 设置一组callback的type
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
// 生成代理类,创建代理实例
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
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);
}
}
做了4件事:
1.从advised 中获取目标对象,判断rootClass是否是Cglib代理所产生的类(内部判断rootClass的className是否包含$$),如果是就取目标类的父类作为目标类
2.验证proxySuperClass中的是否有final方法(有则打印出来警告信息,该方法不能被代理)
3.创建配置Enhancer
4.获取callbacks回调方法有6个(DynamicAdvisedInterceptor、StaticUnadvisedInterceptor(我debug的时候这里是用的这个,不是用的StaticUnadvisedExposedInterceptor)、SerializableNoOp、StaticDispatcher、EqualsInterceptor、HashCodeInterceptor)
5.为Enhancer设置回调过滤callbackFilter(用的ProxyCallbackFilter)和回调类型
6.createProxyClassAndInstance生成代理类,创建代理实例。这里面会用到前面设置进来的callbackFilter。之后专门写一篇文章介绍这个方法。
4.1 getCallbacks 获取回调方法
源码:
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
// 创建callback 这个DynamicAdvisedInterceptor是一个实现了MethodInterceptor接口的类
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
}
else {
// 创建一个callback,是一个实现了MethodInterceptor接口的类
targetInterceptor = isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
// 创建一个callback,是一个实现了MethodInterceptor接口的类
Callback targetDispatcher = isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
// 把7个callback,即是MethodInterceptor放到callback组中
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
// 如果目标是static,并且advicechain是fronze时
// debug的时候没有找到这里面去,暂时不知道这个到底是干嘛的
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
做了1件事:
创建一组cgblic的callbacks,在里面加入了7个MethodInterceptor:
1.DynamicAdvisedInterceptor
2.StaticUnadvisedInterceptor(我debug的时候这里是用的这个,不是用的StaticUnadvisedExposedInterceptor)
3.SerializableNoOp
4.StaticDispatcher
5.AdvisedDispatcher
6.EqualsInterceptor
7.HashCodeInterceptor
五、JdkDynamicAopProxy类的getProxy方法
测试一个有接口的被代理目标类,看一下JdkDynamicAopProxy类的getProxy方法
源码:
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
// 得到代理接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
做了3件事:
1.得到代理接口,这里除了我写的目标类本来实现的接口以外,还有3个(interface org.springframework.aop.SpringProxy、interface org.springframework.aop.framework.Advised、interface org.springframework.core.DecoratingProxy)
2.设置JdkDynamicAopProxy类的equalsDefined和hashCodeDefined属性。
3.生成代理对象。