Spring之ApplicationContext加载含有AOP标签的配置文件的流程

一开始想用DefaultListableBeanFactory 跟踪AOP的源代码,发现它不支持AOP,是不支持还是自己配置错了还没搞清楚,抽空要比较一下BeanFactory下的子类的区别。
ApplicationContext和我们之前的解析配置文件和创建bean的有点区别,之前都是采用的延时创建bean,就是当getBean()的时候,才会去实例化指定的bean,而ApplicationContext是解析玩配置文件马上去实例化bean,接下来,让我们去跟着源代码走一遍流程。
这次我们创建的类有如下几个:
在这里插入图片描述
配置文件如下:
在这里插入图片描述

主要就是想看一下对于AOP是如何解析配置文件和创建实例的。走起!!!

ApplicationContext beanFactory = new ClassPathXmlApplicationContext("beans.xml");

这行代码可是我们这边文章罪恶的源头啊,哈哈哈!这是我们分析代码的入口。

public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		//调用父类的构造方法
		super(parent);
		//设置配置文件的路径
		setConfigLocations(configLocations);
		//看是否需要重新加载配置文件
		if (refresh) {
			refresh();
		}
	}

这个构造方法每一步都很重要,我们先看一下设置配置文件的路径:

public void setConfigLocations(@Nullable String... locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			//实例化存放配置文件路径的数组
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				//解析路径并存到数组里面
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}

我们这次用的IOC容器是ApplicationContext可以一次加载多个配置文件。
Spring刚启动的时候refresh为true,所以需要加载配置文件,进入这个方法去看一下:

	synchronized (this.startupShutdownMonitor) {
			// 为重新读取配置文件准备环境
			prepareRefresh();

			// 声明一个内部的IOC容器
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//准备bean factory,以便在此上下文中使用
			prepareBeanFactory(beanFactory);

			try {
				// 允许在上下文子类中对bean工厂进行后期处理。
				postProcessBeanFactory(beanFactory);

				// 调用上下文中注册为bean的工厂处理器。
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册拦截bean创建的bean处理器。
				registerBeanPostProcessors(beanFactory);

				// 初始化此上下文的消息源。
				initMessageSource();

				//为这个上下文初始化事件多主机。
				initApplicationEventMulticaster();

				//初始化特定上下文子类中的其他特殊bean。
				onRefresh();

				// 检查侦听器bean并注册它们
				registerListeners();

				// 实例化所有剩余的(非延迟-init)单例
				finishBeanFactoryInitialization(beanFactory);

				// 最后一步:发布响应的事件
				finishRefresh();
			}

			catch (BeansException ex) {
				...
			}

			finally {
				//在Spring的内核中重置常见的内省缓存,因为我们可能再也不需要单例bean的元数据了
				resetCommonCaches();
			}
		}
	}

在这个方法中没有一句废话,需要做什么非常清晰,我们就来一个一个方法的进入去看看到底怎么回事:

protected void prepareRefresh() {
		//本次刷新开始的时间
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);
		...
		// 在上下文环境中初始化任何占位符属性源
		initPropertySources();

		// 验证所有标记为必需的属性都是可解析的
		getEnvironment().validate
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <description>Spring公共配置文件</description> <!-- mes 的數據庫 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/> <property name="jdbcUrl" value="jdbc:oracle:thin:@10.142.252.132:1521:mestest"/> <property name="maxPoolSize" value="10"></property> <property name="maxIdleTime" value="1800"></property> <property name="minPoolSize" value="1"></property> <property name="initialPoolSize" value="1"></property> <property name="properties"> <ref bean="mesDatasourcePropertiesFactory" /> </property> </bean> <!-- c3p0数据源的一个专有属性,只可以存放密码和用户名 --> <bean id="mesDatasourcePropertiesFactory" class="com.ccc.db.impl.DatasourcePropertiesFactory" factory-method="getProperties"> <!-- userName--> <constructor-arg type="java.lang.String"> <value>jxg/Qr4VbxU=</value> </constructor-arg> <!-- password --> <constructor-arg type="java.lang.String"> <value>jxg/Qr4VbxU=</value> </constructor-arg> <!-- 生产环境模式 ,才特殊处理密密码--> <constructor-arg type="java.lang.String"> <value>true</value> </constructor-arg> </bean> <!-- ptc windchill的數據庫 --> <bean id="dataSourcePdm" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/> <property name="jdbcUrl" value="jdbc:oracle:thin:@10.142.252.132:1521:mesdev"/> <property name="maxPoolSize" value="10"></property> <property name="maxIdleTime" value="1800"></property> <property name="minPoolSize" value="1"></property> <property name="initialPoolSize" value="1"></property> <property name="properties"> <ref bean="ptcDatasourcePropertiesFactory" /> </property> </bean> <!-- c3p0数据源的一个专有属性,只可以存放密码和用户名 --> <bean id="ptcDatasourcePropertiesFactory" class="com.ccc.db.impl.DatasourcePropertiesFactory" factory-method="getProperties"> <!-- userName--> <constructor-arg type="java.lang.String"> <value>WgDH/SDIJfs=</value> </constructor-arg> <!-- password --> <constructor-arg type="java.lang.String"> <value>WgDH/SDIJfs=</value> </constructor-arg> <!-- 生产环境模式 ,才特殊处理密密码--> <constructor-arg type="java.lang.String"> <value>true</value> </constructor-arg> </bean> <!-- mes數據源代理 --> <bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy" p:targetDataSource-ref="dataSource"/> <!-- 对web包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能--> <context:component-scan base-package="com.ccc"/> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:order="0" /> <!-- 配置事务管理器 針對MES數據庫--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager " p:dataSource-ref="dataSourceProxy"/> <!-- 配置事务的传播特性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 那些类的哪些方法参与事务 --> <aop:config> <aop:pointcut id="allManagerMethod" expression="execution(* com.ccc..*.*(..))"/> <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/> </aop:config> <!-- 配置事务管理器,這個事務性是爭對pdm數據庫的 --> <bean id="transactionManagerPdm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager " p:dataSource-ref="dataSourcePdm"/> <!-- 配置事务的传播特性 --> <tx:advice id="txAdvicePdm" transaction-manager="transactionManagerPdm"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 那些类的哪些方法参与事务 --> <aop:config> <aop:pointcut id="allManagerMethodPdm" expression="execution(* com.ccc.pdm..*.*(..))"/> <aop:advisor pointcut-ref="allManagerMethodPdm" advice-ref="txAdvicePdm"/> </aop:config> <!-- ibatis插件 --> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean" p:dataSource-ref="dataSourceProxy"> <property name="configLocation"> <value>classpath:SqlMapConfig.xml</value> </property> </bean> <bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> <property name="sqlMapClient"> <ref bean="sqlMapClient" /> </property> </bean> <!-- 配置要拦截的url,防止2次提交或做其他數據統計用 <bean id="doubleSubmitInterceptor" class="com.ccc.filter.DoubleSubmitInterceptor"> <property name="mappingURL" value=".html" /> <property name="viewURL" value=".html" /> </bean> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:order="0"> <property name="interceptors"> <list> <ref bean="doubleSubmitInterceptor"/> </list> </property> </bean> --> <!-- JDBC template注入及事務配置 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"><ref bean="dataSourceProxy"/></property> </bean> </beans>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值