spring源码学习之代理类创建过程

上篇中讲到spring将所有的标签解析完成并封装成为RootBeanDefinition之后,并将RootBeanDefinition存储在BeanFactory工厂类的Map<String, BeanDefinition> beanDefinitionMap变量中,这篇接着分析spring使用aop面向切面编程,来实现对事物的控制,spring容器是如何创建目标类的代理类。

BeanPostProcessor创建和注册

从上文中提到的测试用例来看,

public class AuthUserServiceImplTest {
    private static Logger logger = Logger.getLogger(AuthUserServiceImplTest.class);

    public static void main(String[] args){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
        IAuthUserService authUserServiceImpl = ctx.getBean(AuthUserServiceImpl.class);
        Map<String,Object> params = new HashMap<>();
        params.put("userAccount","user002");
        int ret = authUserServiceImpl.delete("user002");
    }
}

执行new ClassPathXmlApplicationContext("bean.xml"),创建ApplicationContext容器,此过程会解析bean.xml配置文件,完成所有的标签解析。refresh()方法主要完成spring 容器的创建过程,此处主要分析registerBeanPostProcessors()方法和finishBeanFactoryInitialization()方法。

public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            //创建工厂,解析标签并将bean封装成为RootBeanDefinition注册到工厂中
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);
            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                //注册后置处理器
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                //创建bean等
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var9);
                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

refresh()方法的调用过程:

后置处理器的注册在registerBeanPostProcessors()方法中完成。方法大概内容如下:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        //在beanFactory工厂类中,根据类型BeanPostProcessor,查找所有的BeanPostProcessor的实现类名字
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
        //存放PriorityOrdered接口的实现类
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList();
        //存放Ordered接口的实现类
        List<String> orderedPostProcessorNames = new ArrayList();
        //存放未实现PriorityOrdered和Ordered接口的后置处理器
        List<String> nonOrderedPostProcessorNames = new ArrayList();
        String[] var8 = postProcessorNames;
        int var9 = postProcessorNames.length;

        String ppName;
        BeanPostProcessor pp;
        for(int var10 = 0; var10 < var9; ++var10) {
            ppName = var8[var10];
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }
        //根据优先级进行排序后置处理器
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        //注册priorityOrdered后置处理器到工厂类中
        registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
        Iterator var14 = orderedPostProcessorNames.iterator();

        while(var14.hasNext()) {
            String ppName = (String)var14.next();
            BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        //根据优先级进行排序后置处理器
        sortPostProcessors(beanFactory, orderedPostProcessors);
        //注册ordered后置处理器到工厂类中
        registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
        Iterator var17 = nonOrderedPostProcessorNames.iterator();

        while(var17.hasNext()) {
            ppName = (String)var17.next();
            pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        //根据未排序的后置处理器
        registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
        sortPostProcessors(beanFactory, internalPostProcessors);
        registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
        beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.ApplicationListenerDetector(applicationContext));
    }

看看 registerBeanPostProcessors()方法的内容:

private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
        Iterator var2 = postProcessors.iterator();
        while(var2.hasNext()) {
            BeanPostProcessor postProcessor = (BeanPostProcessor)var2.next();
            beanFactory.addBeanPostProcessor(postProcessor);
        }

    }

方法接受一个后置处理器的列表,内部逐个处理器完成注册。看看addBeanPostProcessor()方法的内容:

public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        this.beanPostProcessors.remove(beanPostProcessor);
        this.beanPostProcessors.add(beanPostProcessor);
        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            this.hasInstantiationAwareBeanPostProcessors = true;
        }

        if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
            this.hasDestructionAwareBeanPostProcessors = true;
        }

    }

首先删除集合中的BeanPostProcessor,在进行添加,beanPostProcessors集合是工厂类中一个list类型的私有变量private final List<BeanPostProcessor> beanPostProcessors = new ArrayList()。这样就完成了后置处理器BeanPostProcessor的注册。

看看工厂中注册的所有的处理器:

此文不是关注所有的BeanPostProcessor处理器,我们只重点关注和事务代理类相关的处理器AnnotationAwareAspectJAutoProxyCreator

创建代理类

完成后置处理器BeanPostProcessor的注册之后,容器会进行bean对象的创建工作,创建工作主要在finishBeanFactoryInitialization()方法中进行:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        .....
        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
        beanFactory.preInstantiateSingletons();
    }

从方法中看出,直接调用了beanFactory.preInstantiateSingletons(),创建工作还是交给了工厂类来完成,这个beanFactory类的实现类就是DefaultListableBeanFactory。

preInstantiateSingletons方法中遍历集合变量beanDefinitionNames,此变量中存储了容器所有的标签定义。变量内容如下:

@Override
	public void preInstantiateSingletons() throws BeansException {
		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					getBean(beanName);
				}
			}
		}
	}

然后根据beanName调用this.getBean(beanName)方法创建bean。

在实例化之前,beanFactory会遍历所有的后置处理器BeanPostProcessor的postProcessBeforeInstantiation(beanClass, beanName)方法,postProcessBeforeInstantiation方法的具体内容不是此处的重点,忽略,此处我们以authUserServiceImpl实例化为例,分析代理类的创建过程,在创建authUserServiceImpl的过程中会调用后置处理器AnnotationAwareAspectJAutoProxyCreator,在前文中提到过这个处理器,他是<aop:aspectj-autoproxy>标签对应的classbean类,在执行处理器的postProcessBeforeInstantiation方法的过程中会先实例化DefaultBeanFactoryPointcutAdvisor,我们在bean.xml中配置了<aop:advisor>标签,这个标签对应的beanClass类就是DefaultBeanFactoryPointcutAdvisor,这个是Advisor的实现类。spring会解析这个标签并将其封装成为RootBeanDefinition注册到工厂类中。为什么会实例化这个类呢,因为AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation这个方法中会遍历所有的Advisor配置器,为什么遍历所有的Advisor,此处不是分析的重点,忽略。

调用完处理器的postProcessBeforeInstantiation方法之后,接下来就是工厂类调用AuthUserServiceImpl的构造函数,进行authUserServiceImpl的实例化,实例化完成之后,调用工厂类的populateBean(beanName, mbd, instanceWrapper)方法,进行对象属性的赋值,赋值的过程又是一个遍历处理器BeanPostProcessor的过程,此处的处理器是InstantiationAwareBeanPostProcessor,完成实例化之后的属性赋值,赋值的过程中如果依赖其他对象,则会先实例化依赖的对象并进行赋值,之后才能完成authUserServiceImpl的赋值操作。authUserServiceImpl依赖于AuthUserMapper,AuthUserMapper依赖sqlSessionFacory,sqlSessionFacory依赖DataSource。

调用populateBean赋值完成之后,调用initializeBean(beanName, exposedObject, mbd)方法,进行对象的初始化。初始化首先调用处理器BeanPostProcessorpostProcessBeforeInitialization()方法,再调用InitializingBean实现类的afterPropertiesSet方法,再调用InitMethod方法,最后调用处理器BeanPostProcessor的postProcessAfterInitialization方法。

其他的处理器的postProcessAfterInitialization方法不做重点分析,重点分析处理器AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization方法,因为创建代理类的逻辑,在这个处理器中来完成的。

    @Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

处理器首先从beanFactory中根据Advisor.class类型查找出所有Advisor的实现类DefaultBeanFactoryPointcutAdvisor,目前容器中只有一个Advisor的实现类。DefaultBeanFactoryPointcutAdvisor包含两个成员,一个是pointcut,一个是Advice,

而这个Advisor中直接持有pointcut切入点的表达式expression="execution(* com.test.service.*.*(..))",

当前创建的com.test.service.impl.AuthUserServiceImpl对象又符合表达式的要求,知道了pointcut切入点,还需要有advice,而这个advice并没有被实例化,所以此时又会先实例化advice,

@Override
	public Advice getAdvice() {
		synchronized (this.adviceMonitor) {
			if (this.advice == null && this.adviceBeanName != null) {
				Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
				this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
			}
			return this.advice;
		}
	}

adviceBeanName变量的值就是interceptorAdvice,这是我们在bean.xml中配置的advice-ref的值

    <aop:config>
        <aop:pointcut id="transactionPointcut" expression="execution(* com.test.service.*.*(..))"/>
        <aop:advisor pointcut-ref="transactionPointcut" advice-ref="interceptorAdvice"/>
    </aop:config>

实例化advice之后,它引用的就是TransactionInterceptor,它是一个advice也是一个interceptor。为什么是TransactionInterceptor呢?

interceptorAdvice所指向的标签就是tx:advice,spring将tx:advice标签封装成为RootBeanDefinition存储在工厂类中,RootBeanDefinition的classbean就是指向的是TransactionInterceptor,

<!-- 配置通知 -->
    <tx:advice id="interceptorAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="delete*" propagation="REQUIRED" read-only="false" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>

看看tx标签处理器:

public class TxNamespaceHandler extends NamespaceHandlerSupport {
	@Override
	public void init() {
		registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
		registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
	}
}

advice所对应的解析器就是TxAdviceBeanDefinitionParser,解析器的getBeanClass()方法返回值就是TransactionInterceptor.class

回到处理器BeanPostProcessor的postProcessAfterInitialization()方法,调用wrapIfNecessary()方法,

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			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;
	}

调用getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null)方法的目的就是,找到正在创建的AuthUserServiceImpl类,是否符合切入点的要求,如果符合就返回拦截器,就是上面我们找到的TransactionInterceptor。这个拦截器会在以后调用AuthUserServiceImpl的方法的时候起到拦截事物的作用。

既然拦截器是存在的,那就需要创建代理类,调用createProxy()来完成代理类的创建。

protected Object createProxy(
			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);
		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		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(getProxyClassLoader());
	}

首先创建一个ProxyFactory工厂,这个工厂类来完成代理类的创建工作。spring aop在创建代理类的选择上,可以有两种方式创建代理类,一种是jdk的动态代理JdkDynamicAopProxy,另外一种是cglib方式ObjenesisCglibAopProxy。具体怎么选择,看如下代码:

	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);
		}
	}

config.isOptimize()没找到在哪儿设置,默认是false,先不管。

config.isProxyTargetClass()的值就是<aop:aspectj-autoproxy proxy-target-class="true"/>标签中proxy-target-class属性的值,

hasNoUserSuppliedProxyInterfaces(config)判断当前目标类是否实现了某个接口,也就是判断是不是面向接口编程,并且实现了org.springframework.aop.SpringProxy接口,proxy-target-class等于false的时候才会判断是否面向接口编程。

private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
		Class<?>[] ifcs = config.getProxiedInterfaces();
		return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
	}

targetClass.isInterface()表示如果目标类是一个接口,使用jdk的动态代理JdkDynamicAopProxy创建代理类,

Proxy.isProxyClass(targetClass)表示目标类继承了java.lang.reflect.Proxy类,同样也会使用jdk的动态代理JdkDynamicAopProxy创建代理类,

确定采用cglib还是jdk动态代理方式策略之后,就调用getProxy()创建代理类。

代理类创建出来之后,spring将其注册到工厂类中的局部变量中

private final Map<String, Object> singletonObjects = new ConcurrentHashMap(64);

private final Set<String> registeredSingletons = new LinkedHashSet(64);

protected void addSingleton(String beanName, Object singletonObject) {
        Map var3 = this.singletonObjects;
        synchronized(this.singletonObjects) {
            this.singletonObjects.put(beanName, singletonObject != null ? singletonObject : NULL_OBJECT);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }

ok,这就完成了代理类的创建。

从上图中可以看得出来,这个authUserServiceImpl所引用的实例是用cglib的方式创建出来的。

最后附上一张时序图,这张时序图并不代表实际的过程,省略了一些过程,和简化了一些内容。

猜你喜欢

转载自blog.csdn.net/lihuayong/article/details/82950858