目前我們開發功能的流程中,在service層會手動創建SQLSession對象,並使用SQLSession對象獲取Mapper接口的實例化對象,但是我們真正使用的是Mapper接口的對象,目前的代碼編寫方式極大的影響了開發效率,而且mybatis層和service 層之間的耦合性非常高
解決:
使用SpringIOC技術實現service層和mybatis層的解耦:說白了就是讓Spring容器幫我們獲取Mapper層接口的實例化 對象,我們直接從Spring容器中獲取使用即可.
實現:
①導入SpringIOC的jar包
②在src下創建並配置Spring的配置文件
配置DataSource數據源的bean
配置SQLSessionFactory的工廠bean(DataSource的bean)
配置mapper掃描bean對象(SQLSessionFactory對象,掃 描路徑)
③創建Spring容器對象,並獲取Mapper接口的實例化對象完成數據庫操作
Controller層使用Spring解耦service層
問題:
在業務層使用Spring容器對象獲取Mapper接口實例化對象后實現了
service層和mybatis層的解耦,但是在controller層我們依然在Servlet
中直接創建Service對象,耦合性過高.
解決:
將service對象配置為bean對象,Servlet中從Spring容器中
獲取Service對象,完成功能開發.
實現:
①在applicationcontext.xml文件中配置service的bean
②在servlet中的service方法中創建Spring容器對象
③在servlet中的service方法中從Spring容器中獲取 service對象
④使用service對象完成功能處理
[1] MVC項目中使用SpringIOC解耦的代碼優化
問題:
目前的整合中,tomcat服務在接收到請求后,會創建一個線程來處理請求,每個線程之間都是相互獨立運行.流程如下:
①瀏覽器發起登錄請求
②tomcat服務器獲取請求,創建新的線程處理請求
③調用請求的Servlet對象中的service方法
假如10個用戶發起登錄請求,tomcat會創建10個線程處理請求.每個線程都需要調用UserServlet的service方法,而方法的調用依賴UserServlet的實例化對象,那么每個線程都創建一個UserServlet對象,還是UserServlet對象只有一個,但是被10個線程所共享使用呢?假如我們單線程操作,將UserServlet對象的service方法連續調用10此,代碼如下:
UserServlet us=new UserServlet()
us.service();
us.service();
us.service();
us.service();
..........
而在此段代碼中,我們完全可以聲明10個線程,每個線程獨立運行us.service().由此得出結論,在tomcat創建線程處理請求時,Servlet對象只會被創建一次,Servlet對象是多線程共享的.那么Servlet什么時候被創建呢?
默認在第一次請求的時候被創建,往后就不會再次重新創建了,如果配置了loadOnStartUp則在服務器啟動的時候就會完成初始化創建.
④Servlet中的service方法被執行,service方法進棧.
然后創建Spring容器對象,內存堆中就會出現一個Spring容 器對象s1,而s1被創建的時候,會加載spring的配置文件,根 據配置文件創建對象(dataSource,factory,mapper,us).
⑤獲取Spring容器中的業務層對象us
⑥調用us對象的登錄業務方法
⑦登錄業務方法進棧,又會創建一個新的Spring容器對象s2,
而s2被創建的時候,又加載解析Spring的配置文件,又創建 dataSource,factory,us,mapper的bean對象.
⑧在業務的登錄方法中獲取s2容器對象中的mapper對象完成 數據庫操作,執行業務處理,登錄業務方法處理完畢,返回結果 給controller的service方法,然后業務方法出棧.
⑨servlet的service方法獲取到業務層的返回值后,繼續處理,然后響應處理結果給瀏覽器,service方法結束,service方法出棧,請求處理完畢,線程銷毀.
通過以上流程發現,目前的代碼的結構,一個線程中會存在除Servlet對象以外10個對象,一旦高並發訪問,會造成內存資源的極大的浪費,造成項目崩潰.
解決:
優化代碼中的資源占比.