一、前言
在上一节中我们已经介绍了在createBean过程中去执行AspectJAutoProxyCreator的after方法,然后去获取当前bean适配的advisor,如果还不熟悉的可以去看下之前的博客,接下来我们分析Spring AOP是如何创建代理对象的,在此之前如果对于JDK动态代理以及cglib源码不熟悉的也先去看一下之前对于这两个代理的源码分析博客。Spring源码解析(24)之JDK动态代理与cglib动态代理源码解析_spring 选择 jdk 代理 cglib 代理源码-CSDN博客
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果已经处理过,直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 这里advisedBeans缓存了已经进行了代理的bean,如果缓存中存在,则可以直接返回
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 这里isInfrastructureClass()用于判断当前bean是否为Spring系统自带的bean,自带的bean是
// 不用进行代理的;shouldSkip()则用于判断当前bean是否应该被略过
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
// 对当前bean进行缓存
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 获取当前bean的Advices和Advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 对当前bean的代理状态进行缓存
if (specificInterceptors != DO_NOT_PROXY) {
// 对当前bean的代理状态进行缓存
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 根据获取到的Advices和Advisors为当前bean生成代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 缓存生成的代理bean的类型,并且返回生成的代理bean
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
二、源码分析
接下来我们继续分析createProxy方法,来看下Spring AOP是如何创建代理对象的。
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// 给bean定义设置暴露属性
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 获取当前类中相关属性
proxyFactory.copyFrom(this);
// 决定对于给定的bean是否应该使用targetClass而不是他的接口代理,检查proxyTargetClass设置以及preserverTargetClass属性
if (!proxyFactory.isProxyTargetClass()) {
// 判断是 使用jdk动态代理 还是cglib代理
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 添加代理接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 构建增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 设置到要代理的类
proxyFactory.setTargetSource(targetSource);
// 定制代理
customizeProxyFactory(proxyFactory);
// 控制代理工程被配置之后,是否还允许修改通知,默认值是false
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 真正创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
设置一系列属性,然后判断是否有proxyTargetClass来决定是使用cglib代理还是JDK代理。
public Object getProxy(@Nullable ClassLoader classLoader) {
// createAopProxy() 用来创建我们的代理工厂
return createAopProxy().getProxy(classLoader);
}
首先会在createAopProxy中判断是使用cglib代理还是jdk动态代理。
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
// 监听调用AdvisedSupportListener实现类的activated方法
activate();
}
// 通过AopProxyFactory获得AopProxy,这个AopProxyFactory是在初始化函数中定义的,使用的是DefaultAopProxyFactory
return getAopProxyFactory().createAopProxy(this);
}
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
/**
* Create a new ProxyCreatorSupport instance.
*/
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
所以最终会调到DefaultAopProxyFactory中去判断,继续往下跟。
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 这段代码用来判断选择哪种创建代理对象的方式
// config.isOptimize() 是否对代理类的生成使用策略优化 其作用是和isProxyTargetClass是一样的 默认为false
// config.isProxyTargetClass() 是否使用Cglib的方式创建代理对象 默认为false
// hasNoUserSuppliedProxyInterfaces目标类是否有接口存在 且只有一个接口的时候接口类型不是SpringProxy类型
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 上面的三个方法有一个为true的话,则进入到这里
// 从AdvisedSupport中获取目标类 类对象
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.");
}
// 判断目标类是否是接口 如果目标类是接口的话,则还是使用JDK的方式生成代理对象
// 如果目标类是Proxy类型 则还是使用JDK的方式生成代理对象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 配置了使用Cglib进行动态代理或者目标类没有接口,那么使用Cglib的方式创建代理对象
return new ObjenesisCglibAopProxy(config);
}
else {
// 使用JDK的提供的代理方式生成代理对象
return new JdkDynamicAopProxy(config);
}
}
上面就能够判断得到是使用cglib动态还是还是jdk动态代理,如果使用的是cglib动态代理则返回ObjenesisCglibAopProxy,否则则返回JkdDynamicAopProxy对象。
我们继续往下跟getProxy方法,看他是如果创建代理对象的。
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 从advised中获取ioc容器中配置的target对象
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
//如果目标对象已经是CGLIB 生成代理对象(就是比较类名称中有 $$ 字符串),那么就取目标对象的父类作为目标对象的类
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
// 获取原始父类的接口
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
// 打印出不能代理的方法名,CGLIB 是使用继承实现的,所以final , static 的方法不能被增强
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 ClassLoaderAwareGeneratorStrategy(classLoader));
// 获取callbacks
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
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
// 通过 Enhancer 生成代理对象,并设置回调
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + 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);
}
}
首先看一下AopProxyUtils.completeProxiedInterfaces(this.advised)。
这个方法会给我们的代理类加上两个接口,一个是SpringProxy,是一个advised对象,我们之前了解过advisor对象是一个通知器,他里面包含有advice和pointcut对象,而advice对象就是具体的某一个消息通知,那么advised是干啥的?我们来看下他的方法以及他是在那里生成的。
其实他就是ProxyFactory对象,就是用来配置代理的,那么他是在哪里赋值的呢?我们回到我们判断是使用哪种代理方式那里。
而我们的ProxyFactory就是继承ProxyCreatorSupport的。
然后看一下他是如何设置我们的回调方法的,继续往下跟 getCallbacks方法。
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
// 对于expose-proxy属性的处理,是否暴露当前对象为ThreadLocal模式,在当前上下文中能够进行引用
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
// 将拦截器封装在DynamicAdvisedInterceptor中
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 {
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 targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
Callback[] mainCallbacks = new Callback[] {
// 将拦截器链加入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.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, 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;
}
最后他封装了这些回调方法。第一个Callback是DynamicAdvisorInterceptor.
然后就会调具体的createProxyClassAndInstance来创建代理对象了,继续往下跟。
@Override
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
Class<?> proxyClass = enhancer.createClass();
Object proxyInstance = null;
if (objenesis.isWorthTrying()) {
try {
proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
}
catch (Throwable ex) {
logger.debug("Unable to instantiate proxy using Objenesis, " +
"falling back to regular proxy construction", ex);
}
}
if (proxyInstance == null) {
// Regular instantiation via default constructor...
try {
Constructor<?> ctor = (this.constructorArgs != null ?
proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
proxyClass.getDeclaredConstructor());
ReflectionUtils.makeAccessible(ctor);
proxyInstance = (this.constructorArgs != null ?
ctor.newInstance(this.constructorArgs) : ctor.newInstance());
}
catch (Throwable ex) {
throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
"and regular proxy instantiation via default constructor fails as well", ex);
}
}
((Factory) proxyInstance).setCallbacks(callbacks);
return proxyInstance;
}
public Class createClass() {
classOnly = true;
return (Class) createHelper();
}
private Object createHelper() {
// 校验callbackTypes、filter是否为空,以及为空时的处理
preValidate();
// 通过newInstance方法来创建EnhancerKey对象,正常情况下,只需要new一个对象就可以调用方法了,但是Key_Factory是一个EnhancerKey类型,是一个内部接口,需要动态代理来实现,最终是为了调用newInstance方法
Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
ReflectUtils.getNames(interfaces),
filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter),
callbackTypes,
useFactory,
interceptDuringConstruction,
serialVersionUID);
// 设置当前enhancer的代理类的key标识
this.currentKey = key;
// 调用父类即AbstractClassGenerator的创建代理类
Object result = super.create(key);
return result;
最后就会返回一个创建好的代理对象.
然后回到我们获取得到这个代理对象,然后调用对应的代理方法,这时候会怎么去执行呢?很明显因为我们第一个放入的是DynamicAdvisorInterceptor对象,所以第一个就会进入到这个拦截器中。
public static void main(String[] args) throws Exception {
// saveGeneratedCGlibProxyFiles(System.getProperty("user.dir")+"/proxy");
ApplicationContext ac = new ClassPathXmlApplicationContext("aop.xml");
MyCalculator bean = ac.getBean(MyCalculator.class);
System.out.println(bean.toString());
bean.add(1,1);
bean.sub(1,1);
}
这里想一下,我们有这么多通知切面,他是如何去判断这些通知的执行顺序 。
在spring他是通过一个责任链模式来组装一个链式结构,不知道还是否继续要之前获取当前bean适配的advisor后会给所有的advisor集合中添加一个exposeInvocationInterceptor对象,是通过这个对象来判断当前执行的是哪个advisor对象,这个具体会在下一节中具体介绍。