Spring初始化ApplicationContext線程託管實際運用架構構思

來源:互聯網
上載者:User

標籤:extc   ogg   其他   name   初始化   arc   return   led   actions   

今天我分享一個技術點,利用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("25");        custServer.insertTest(customer);    }}

(1) 跑一遍單元測試,INFO日誌輸出:

16:34:30,296  INFO DefaultTestContextBootstrapper:259 - 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]16:34:30,313  INFO DefaultTestContextBootstrapper:185 - Using TestExecutionListeners: [or[email protected]146ba0ac, org.springframework.test[email protected]4dfa3a9d, org.springframewor[email protected]6eebc39e, org.springfra[email protected]464bee09, org.springframew[email protected]f6c48ac, org.sp[email protected]13deb50e]16:34:30,390  INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [applicationContext.xml]16:34:30,685  INFO GenericApplicationContext:578 - Refreshing [email protected]0736d9: startup date [Mon Aug 07 16:34:30 CST 2017]; root of context hierarchy16:34:30,777  INFO PropertyPlaceholderConfigurer:172 - Loading properties file from class path resource [init.properties]16:34:30,970  INFO MLog:212 - MLog clients using slf4j logging.16:34:31,123  INFO C3P0Registry:212 - Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]16:34:31,296  INFO Version:37 - HHH000412: Hibernate Core {5.0.8.Final}16:34:31,298  INFO Environment:213 - HHH000206: hibernate.properties not found16:34:31,299  INFO Environment:317 - HHH000021: Bytecode provider name : javassist16:34:31,336  INFO Version:66 - HCANN000001: Hibernate Commons Annotations {5.0.1.Final}16:34:31,416  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 -> 1bqudj89p1g46yu313x3lsl|41ab013, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1bqudj89p1g46yu313x3lsl|41ab013, 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 ]16:34:31,633  INFO Dialect:156 - HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect16:34:31,671  INFO LobCreatorBuilderImpl:98 - HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 416:34:32,027  INFO SchemaUpdate:105 - HHH000228: Running hbm2ddl schema update16:34:32,120  INFO HibernateTransactionManager:357 - Using DataSource [com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> 1bqudj89p1g46yu313x3lsl|41ab013, dataSourceName -> 1bqudj89p1g46yu313x3lsl|41ab013 ]] of Hibernate SessionFactory for HibernateTransactionManagerHibernate: select next_val as id_val from hibernate_sequence for updateHibernate: update hibernate_sequence set next_val= ? where next_val=?Hibernate: insert into customer (cage, cinfo, cname, id) values (?, ?, ?, ?)16:34:32,487  INFO GenericApplicationContext:960 - Closing [email protected]0736d9: startup date [Mon Aug 07 16:34:30 CST 2017]; 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[email protected]7ce6a65d: startup date [Tue Aug 08 09:43:35 CST 2017]; root of context hierarchy09: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線程託管實際運用架構構思

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.