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

来源:http://www.cnblogs.com/KuJo/archive/2017/08/08/7305295.html
-Advertisement-
Play Games

今天我分享一個技術點,利用Spring初始化+線程接管進行程式啟動後保持會話狀態。 先來一段@test單元測試註解,後臺開發的很熟悉,這是測試局部代碼用的: RunWith和ContextConfiguration的源碼和功能就不細解釋了,不熟悉的可以去翻翻源碼。 1:我來一段@Test單元測試操作 ...


今天我分享一個技術點,利用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: [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]
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 org.springframework.context.support.GenericApplicationContext@370736d9: startup date [Mon Aug 07 16:34:30 CST 2017]; root of context hierarchy
16: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 found
16:34:31,299  INFO Environment:317 - HHH000021: Bytecode provider name : javassist
16: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.MySQLDialect
16:34:31,671  INFO LobCreatorBuilderImpl:98 - HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
16:34:32,027  INFO SchemaUpdate:105 - HHH000228: Running hbm2ddl schema update
16:34:32,120  INFO HibernateTransactionManager:357 - 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 (?, ?, ?, ?)
16:34:32,487  INFO GenericApplicationContext:960 - Closing org.springframework.context.support.GenericApplicationContext@370736d9: 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 jdbcTemplate= (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)代碼控制它保持後臺運行會話狀態。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • t = (1, 2, ‘hl’)x, y, z = t上述方法可用於任何sequence ...
  • package com.hd.action; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServlet; import javax.servlet.http.Htt... ...
  • 1568: [JSOI2008]Blue Mary開公司 Description Input 第一行 :一個整數N ,表示方案和詢問的總數。 接下來N行,每行開頭一個單詞“Query”或“Project”。 若單詞為Query,則後接一個整數T,表示Blue Mary詢問第T天的最大收益。 若單詞為 ...
  • 我的理解: 拿clean舉例,如果make完成後,自己另外定義一個名叫clean的文件,再執行make clean時,將不會執行rm命令。 為了避免出現這個問題,需要.PHONY: clean 所謂偽目標就是這樣一個目標,它不代表一個真正的文件名,在執行make時可以指定這個目標來執行其所在規則定義 ...
  • 加 Golang學習 QQ群共同學習進步成家立業工作 ^-^ 群號:96933959 Goroutine Go語言的主要的功能在於令人簡易使用的並行設計,這個方法叫做Goroutine,通過Goroutine能夠讓你的程式以非同步的方式運行,而不需要擔心一個函數導致程式中斷,因此Go語言也非常地適合網 ...
  • 題目:通告發佈管理系 語言和環境 A、實現語言 Java B、環境要求 JDK 7.0、Eclipse、Tomcat 7、SQL Server 2008 功能要求 使用JSP實現“通告發佈管理系統”功能,使用SQL Server 2008 作為資料庫,功能包括查詢所有的通告信息與通告信息的修改兩大功 ...
  • 寫在前面: 最近在項目中,遇到一個問題,在點擊一個超鏈接時,頁面報錯。通過瀏覽器調試就可以知道發送的請求參數是不完整的,因為參數中含有特殊字元。所以就報錯啦~~ 原代碼,不能正確發送含有特殊字元的參數: 其中k_projectname中是含有特殊字元的,比如#,在發送請求的時候就不能被識別,需要對其 ...
  • 閱讀目錄: 事件綁定 Toplevel組件 標準對話框 事件綁定 事件綁定: 說明:對於每個組件來說,可以通過bind()方法將函數或方法綁定到具體的事件上。 事件序列: 說明:用戶需要使用bind()方法將具體的事件序列與自定義的方法綁定,時間序列是以字元串的形式表示的。 語法描述: <modif ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...