spring aop代理对象的产生(二)

前言

我们接着 spring aop代理对象的产生(一) 来分析 aop 代理对象的产生,上篇文章解读到了 AbstractAutowireCapableBeanFactoryinitializeBean 方法,我们继续

aop 代理对象的产生

initializeBean 方法重点关注 applyBeanPostProcessorsAfterInitialization 方法

AOP 的原理和实现就在其中,来到了AbstractAutowireCapableBeanFactoryapplyBeanPostProcessorsAfterInitialization 方法

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
    
    
		
		// 初始化返回结果为existingBean
		Object result = existingBean;
		// 遍历该工厂创建的所有实现了 BeanPostProcessors 接口的列表的 bean
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
    
    
			// 回调BeanPostProcessor#postProcessAfterInitialization来对现有的bean实例进行包装
			Object current = processor.postProcessAfterInitialization(result, beanName);
			// 一般processor对不感兴趣的bean会回调直接返回result,使其能继续回调后续的BeanPostProcessor
			// 但有些processor会返回null来中断其后续的BeanPostProcessor
			if (current == null) {
    
    
				// 直接返回result,中断其后续的BeanPostProcessor处理
				return result;
			}
			result = current;
		}
		return result;
}

查看 postProcessAfterInitialization 方法的实现

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
    
    
	// 只是返回一个 bean
	return bean;
}

查看 getBeanPostProcessors() 方法

在这里插入图片描述
查看 AnnotationAwareAspectJAutoProxyCreator 的类层次结构(查看),可知,其实现了 beanPostProcessor 接口,实现类为 AbstractAutoProxyCreator

AbstractAutoProxyCreatorpostProcessAfterInitialization 方法

主要看这个方法,在 bean 初始化之后对生产出的 bean 进行包装代理

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    
    
    if (bean != null) {
    
    
        // 如果是普通bean,则返回beanName,如果是FactoryBean,则返回加上前缀&的&beanName
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        // earlyProxyReferences中缓存的是已经创建好的代理对象
        if (!this.earlyProxyReferences.contains(cacheKey)) {
    
    
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

AbstractAutoProxyCreatorwrapIfNecessary 方法

判断 bean 是否需要被代理

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    
    
    // 也是看看有没有缓存,有缓存对象就直接返回了
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
    
    
        return bean;
    }
    // 如果该bean不需要被代理,则直接返回原始的bean对象
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
    
    
        return bean;
    }
    
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
    
    
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
 	
 	// 获取 bean 的 advices(通知或增强器)
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
    
    
    	// 加入缓存中
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 通过createProxy方法创建代理对象
        Object proxy = createProxy(
                bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }
 
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

在这里插入图片描述
AbstractAutoProxyCreatorcreateProxy 方法创建代理对象

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
        @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    
    
 
    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
    
    
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }
 	
 	// 创建一个ProxyFactory
    ProxyFactory proxyFactory = new ProxyFactory();
    // 初始化ProxyFactory
    proxyFactory.copyFrom(this);
 
 	// 确定代理方式是使用JDK代理,还是使用Cglib
    if (!proxyFactory.isProxyTargetClass()) {
    
    
        if (shouldProxyTargetClass(beanClass, beanName)) {
    
    
        	// proxyTargetClass默认是false使用JDK代理,反之使用Cglib
            proxyFactory.setProxyTargetClass(true);
        }
        else {
    
    
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }
    // 就是把specificInterceptors中的advisors和commonInterceptors中的拦截器合并(如果有的话)在一起封装成Advisor返回
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    // 将advisors(本案例的四个通知)和源对象设置到proxyFactory上
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);
 	
    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
    
    
        proxyFactory.setPreFiltered(true);
    }
    
    // 真正去创建代理对象了
    return proxyFactory.getProxy(getProxyClassLoader());
}

跟进 getProxy() 方法,在类 ProxyFactory

public Object getProxy(@Nullable ClassLoader classLoader) {
    
    
	return createAopProxy().getProxy(classLoader);
}

继续 ProxyCreatorSupport 类中的 createAopProxy() 方法

protected final synchronized AopProxy createAopProxy() {
    
    
	if (!this.active) {
    
    
		activate();
	}
	return getAopProxyFactory().createAopProxy(this);
}

跟进 DefaultAopProxyFactory 类的 createAopProxy() 方法

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    
    

    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
    
    
        // 获得被代理对象的类型,以确定代理的方式
        Class<?> targetClass = config.getTargetClass();
        // 如果对象类型是接口,或者是JAVA的动态代理类,那么就调用JDK的动态代理方法生成代理对象
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
    
    
            return new JdkDynamicAopProxy(config);
        }
        // 否则使用CGLIB生成代理对象
        return new ObjenesisCglibAopProxy(config);
    }
    else {
    
    
        return new JdkDynamicAopProxy(config);
    }
}

使用 JDK 的动态代理方法生成代理对象

JdkDynamicAopProxy类实现了 InvocationHandler接口,则必定有 invoke 方法,来被调用,也就是用户调用 bean 相关方法时,此 invoke() 被真正调用

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable
    
    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);
        
        // JDK proxy 动态代理的标准用法
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

aop 代理对象产生大概流程步骤小结

  1. IOC 容器启动初始化时,首先会去一级缓存 singletonObjects 中去获取(肯定没有)
  2. 在根据当前 bean 的具体作用域,去初始化 bean
  3. 在做完 bean 的一些校验之后,会调用 createBeanInstance 去实例化 bean
  4. 如果存在 bean 的循环依赖的情况,会将当前已实例化的 bean put 进三级缓存 singletonFactories
  5. 接着会进行 bean 的相关属性填充,注意此时还并没有产生代理对象
  6. 再接着会进行 bean 的初始化操作,调用 initializeBean 方法
  7. 遍历该工厂创建的所有实现了 BeanPostProcessors 接口的列表的 bean
  8. 判断这些 bean 需不需要被代理,如果不需要,则直接返回原始 bean,此时单例 bean 已完成向 IOC 容器的注册工作
  9. 如果需要,再确定代理方式是使用 JDK 代理,还是使用 Cglib
  10. 获取当前 bean 的所有 advices可理解为通知或增强器
  11. 根据代理方式,正式的去创建代理对象,此时代理对象就产生了

参考:https://blog.csdn.net/wuyuwei/article/details/88357698

猜你喜欢

转载自blog.csdn.net/weixin_38192427/article/details/113520109
今日推荐