Spring初始化ApplicationContext线程托管实际运用架构构思
今天我分享一个技术点,利用Spring初始化+线程接管进行程序启动后保持会话状态。
先来一段@test单元测试注解,后台开发的很熟悉,这是测试局部代码用的:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml")
RunWith和ContextConfiguration的源码和功能就不细解释了,不熟悉的可以去翻翻源码。
1:我来一段@Test单元测试操作数据的代码:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class RunTest {
@Autowired
CustomerServices custServer;//services层,注入了dao层
@Test
public void test(){
Customer customer = new Customer();
customer.setCname("余根海");
customer.setCinfo("我是一条鱼!");
customer.setCage(");
custServer.insertTest(customer);
}
}
(1) 跑一遍单元测试,INFO日志输出:
::, INFO DefaultTestContextBootstrapper: - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
::, INFO DefaultTestContextBootstrapper: - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@146ba0ac, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@4dfa3a9d, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@6eebc39e, org.springframework.test.context.support.DirtiesContextTestExecutionListener@464bee09, org.springframework.test.context.transaction.TransactionalTestExecutionListener@f6c48ac, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@13deb50e]
::, INFO XmlBeanDefinitionReader: - Loading XML bean definitions from class path resource [applicationContext.xml]
::, INFO GenericApplicationContext: - Refreshing org.springframework.context.support.GenericApplicationContext@370736d9: startup date [Mon Aug :: CST ]; root of context hierarchy
::, INFO PropertyPlaceholderConfigurer: - Loading properties file from class path resource [init.properties]
::, INFO MLog: - MLog clients using slf4j logging.
::, INFO C3P0Registry: - Initializing c3p0--December- :: -; debug? ]
::, INFO Version: - HHH000412: Hibernate Core {.Final}
::, INFO Environment: - HHH000206: hibernate.properties not found
::, INFO Environment: - HHH000021: Bytecode provider name : javassist
::, INFO Version: - HCANN000001: Hibernate Commons Annotations {.Final}
::, INFO AbstractPoolBackedDataSource: - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> , acquireRetryAttempts -> , acquireRetryDelay -> , autoCommitOnClose -> , connectionCustomizerClassName -> , initialPoolSize -> , jdbcUrl -> jdbc:mysql://127.0.0.1:3306/yugh?useUnicode=true&characterEncoding=utf-8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 30, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 5, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
::, INFO Dialect: - HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
::, INFO LobCreatorBuilderImpl: - HHH000423: Disabling contextual LOB creation ] less than
::, INFO SchemaUpdate: - HHH000228: Running hbm2ddl schema update
::, INFO HibernateTransactionManager: - Using DataSource [com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> 1bqudj89p1g46yu313x3lsl|41ab013, dataSourceName -> 1bqudj89p1g46yu313x3lsl|41ab013 ]] of Hibernate SessionFactory for HibernateTransactionManager
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into customer (cage, cinfo, cname, id) values (?, ?, ?, ?)
::, INFO GenericApplicationContext: - Closing org.springframework.context.support.GenericApplicationContext@370736d9: startup date [Mon Aug :: CST ]; root of context hierarchy
(2) 可以看到@Test单元测试初始化了一遍Spring和Spring文件里的所有配置,因为要操作数据对象,在大部分后台单元测试中,目的都是数据交互。
@Test总结:通过@Test单元测试可以得到初始化Spring以及加载完毕已经配置到Spring文件中所有正确的配置参数,虽然它运行是短暂的。
请忽略上面的Hibernate,虽然上面测试是hibernate作为持久层,但本文所有知识点都是Spring,包括用Spring的数据控制替换其他持久层。
2:得到了初始化的目的,下面就得用线程接管初始化后的操作,几个关键点:(1)初始化spring文件 (2)事务用谁,怎么用,能否成功?(3)线程何时去接管?
静态对象是保持对象唯一,保持初始化的唯一,因为用@TEST单元测试时候,注解RunWith是把测试类和方法名都反射了,已经得到了真实的功能类入口,而我们自己初始化Spring启动程序不用@TEST注解就要定义全局静态对象。
(1):初始化Spring文件,文件加载方式是我常用的:
public static final ApplicationContext CONTEXT = new ClassPathXmlApplicationContext("applicationContext.xml");
(2):事务采用Spring的:dataSource是数据库的bean
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
写下获取事务的静态对象:
static final PlatformTransactionManager MANAGER = (PlatformTransactionManager)CONTEXT.getBean("transactionManager");
(3):数据控制对象jdbctemplate,前身jdbcAccessor,源码用的基于sql的DataSource:
public static final JdbcTemplate JDBC_TEMPLATE = (JdbcTemplate)CONTEXT.getBean("jdbcTemplate");
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
(4) 到这里的配置菜单有:初始化Spring文件 + 事务 + 数据控制对象,虽然全部依赖Spring,但已经是一个很优秀的纯后台项目架构了,虽然在持久层没有hibernate那么强大各种操作方式。
最后来一段Spring初始化日志:
09:43:35,326 INFO ClassPathXmlApplicationContext:578 - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7ce6a65d: startup date [Tue Aug 08 09:43:35 CST 2017]; root of context hierarchy
09:43:35,368 INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [applicationContext.xml]
09:44:21,994 INFO PropertyPlaceholderConfigurer:172 - Loading properties file from class path resource [init.properties]
09:44:24,847 INFO MLog:212 - MLog clients using slf4j logging.
09:44:25,007 INFO C3P0Registry:212 - Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
09:44:33,517 INFO AbstractPoolBackedDataSource:212 - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 30000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1bqudj89p1h4zfam1rricvn|62e8f862, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1bqudj89p1h4zfam1rricvn|62e8f862, idleConnectionTestPeriod -> 30, initialPoolSize -> 5, jdbcUrl -> jdbc:mysql://127.0.0.1:3306/yugh?useUnicode=true&characterEncoding=utf-8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 30, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 5, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
总结构思:(1)利用代码初始加载Spring文件 ——> (2)主入口定义一个main方法,各种校验运行后,运行 ——> (3)调用静态的初始化代码,开始初始 ——> (4) 初始完毕后调用数据控制 ——> (5)通过一系列后台操作后,线程开始接管 ——> (6)代码控制它保持后台运行会话状态。
Spring初始化ApplicationContext线程托管实际运用架构构思的更多相关文章
- Spring初始化ApplicationContext为null
1. ApplicationContextAware初始化 通过它Spring容器会自动把上下文环境对象调用ApplicationContextAware接口中的setApplicationConte ...
- Spring中ApplicationContext加载机制和配置初始化
Spring中ApplicationContext加载机制. 加载器目前有两种选择:ContextLoaderListener和ContextLoaderServlet. ...
- Spring获取ApplicationContext方式,和读取配置文件获取bean的几种方式
转自:http://chinazhaokeke.blog.163.com/blog/static/109409055201092811354236 Spring获取ApplicationContex ...
- 怎么获取Spring的ApplicationContext
在 WEB 开发中,可能会非常少须要显示的获得 ApplicationContext 来得到由 Spring 进行管理的某些 Bean, 今天我就遇到了,在这里和大家分享一下, WEB 开发中,怎么获 ...
- spring提供的线程池
SPRING中的线程池ThreadPoolTaskExecutor 分类: JAVA Spring2013-07-12 10:36 14896人阅读 评论(9) 收藏 举报 Spring线程池多线程 ...
- Spring:ApplicationContext (2)
在使用Spring时,通常会配置一个applictioncontext.xml 来指定ApplicationContext的相关信息. 当使用SpringMVC时,还会再另外指定一个[server-n ...
- Spring容器-ApplicationContext的单例设计
Spring容器-ApplicationContext的单例设计 每次通过new创建一个ApplicationContext容器,都会执行refresh方法,看源代码了解到这个refresh方法会 ...
- Spring中ApplicationContext加载机制
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp33 加载器目前有两种选择:ContextLoaderListener和Co ...
- 获取spring的ApplicationContext几种方式【转】
转自:http://blog.sina.com.cn/s/blog_9c7ba64d0101evar.html Java类获取spring 容器的bean 常用的5种获取spring 中bean的方式 ...
随机推荐
- css3自适应圆
.class{ width:auto; height:auto; border-radius:11px; min-width:14px; padding:0 4px; font-size:12px; ...
- LODOP之票据连续套打笔记<一>
之前项目中需要使用套打,费了半天劲,最后找到LODOP,整体感觉还是不错,简单,满足大多数web套打 这是我项目中需要打印的票据 该票据每张做多显示6条数据,数据超过6条的时候需要进行分页打印,当时做 ...
- [leetcode-485-Max Consecutive Ones]
Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Input: [1, ...
- Gist - ES6 Promise
The concept of "Promise" Promise is used to asynchronous computations. Introduction " ...
- laravel怎么创建一个简单的blog
主要功能实现:点击标题跳转 第一步:创建路由: Route::get('/articles','ArticlesController@index'); Route::get('/articles/{i ...
- [转]浅谈C++指针直接调用类成员函数
找了一番之后发现这篇文章讲的很清楚. 传送门
- js或者jq的tab切换
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- Hibernate错误:Exception in thread "main" org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
报错:Exception in thread "main" org.hibernate.exception.SQLGrammarException: Could not execu ...
- H3CNE实验:通过Console端口本地访问H3C设备
连接好Console线后,将交换机开机,在SecureCRT上会显示如下信息: Starting...... RAMLine.....OK System is booting............. ...
- java在的数据类型
java数据类型的划分 程序的本质=数据的处理: 数据库的本质=数据的存储. java之中数据类型一共分为两大类. ·基本数据类型: 数值型: 整型:byte,short,int,long 默认值都是 ...