一、 spring是什麼?
我們知道struts 是 web 框架 (jsp/action/actionfrom)。hibernate 是 orm框架,處於持久層。
spring 是容器框架,用於配置bean,並維護bean之間關系的框架。
spring中非常重要的概念:
bean (是java中的任何一種對象 javabean/service/action/數據源./dao
ioc(控制反轉 inverse of control)
di( dependency injection 依賴注入)
二、 快速入門
開發一個spring項目.
1.引入spring的開發包(最小配置spring.jar 該包把常用的jar都包括, 還要 寫日志包 common-logging.jar
2.創建spring的一個核心文件(容器文件) applicationContext.xml, [hibernate有核心 hibernate.cfg.xml struts核心文件 struts-config.xml], 該文件一般放在src目錄下,該文件中引入 xsd文件 :可以從給出的案例中拷貝一份.
3.配置bean
<!-- 在容器文件中配置bean(service/dao/domain/action/數據源) -->
<!-- bean元素的作用是,當我們的spring框架加載時候,spring就會自動的創建一個bean對象,並放入內存
UserService userSerivce=new UserService();
userSerivce.setName("韓順平");
-->
<bean id="userService" class="com.service.UserService">
<!-- 這裡就體現出注入的概念. -->
<property name="name">
<value>韓順平</value>
</property>
</bean>
4.在Test.java中,我們怎麼使用
//我們現在使用spring來完成上面的任務
//1.得到spring 的applicationContext對象(容器對象)
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService us=(UserService) ac.getBean("userService");
us.sayHello();
討論:
傳統的方法和使用spring的方法
1.使用spring ,沒有new 對象,我們把創建對象的任務交給spring框架
2.spring的運行原理圖:
總結:
spring實際上是一個容器框架,可以配置各種bean(action/service/domain/dao),並且可以維護bean與bean的關系,當我們需要使用某個bean的時候,我們可以getBean(id),使用即可.
ioc是什麼?
答 :ioc(inverse of controll ) 控制反轉: 所謂控制反轉就是把創建對象(bean),和維護對象(bean)的關系的權利從程序中轉移到spring的容器(applicationContext.xml),而程序本身不再維護.
DI是什麼?
答: di(dependency injection) 依賴注入: 實際上di和ioc是同一個概念,spring設計者認為di更准確表示spring核心技術
注意:Applicationcontext是一個重量級對象,所以要把Applicationcontext做成一個單例的。
三、spring與接口編程
spring開發提倡接口編程,配合di技術可以層與層的解耦
舉例說明:
現在我們體驗一下spring的di配合接口編程的,完成一個字母大小寫轉換的案例思路:
在業務層中使用接口調用方式,改變Spring容器中的配置切換不同的接口實現方式即可改變業務邏輯而不需要改變業務層的代碼。
通過上面的案例,我們可以初步體會到di配合接口編程,的確可以減少層(web層) 和 業務層的耦合度.
四、從ApplicationContext 應用上下文容器中獲取bean和從bean工廠容器中獲取bean
具體案例:
//從ApplicationContext中取bean
ApplicationContext ac=new ClassPathXmlApplicationContext("com/hsp/ioc/beans.xml");
//當我們去實例化beans.xml,該文件中配置的bean被實例(該bean scope是 singleton)從bean中取出student
//如果我們使用beanfactory去獲取bean,當你只是實例化該容器, 那麼
//容器的bean不被實例化,只有當你去使用getBean某個bean時,才會實時的創建.
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("com/hsp/ioc/beans.xml"));
factory.getBean("student");
結論:
1.如果使用ApplicationContext ,則配置的bean如果是 singleton (非singleton則不會)不管你用不用,都被實例化.(好處就是可以預先加載,缺點就是耗內存)
2.如果是 BeanFactory ,則當你獲取beanfacotry時候,配置的bean不會被馬上實例化,當你使用的時候,才被實例(好處節約內存,缺點就是速度)
3.規定: 一般沒有特殊要求,應當使用ApplicatioContext完成
三種獲取ApplicationContext 對象引用的方法
1.ClassPathXmlApplicationContext -> 通過類路徑
2.FileSystemXmlApplicationContext -> 通過文件路徑
舉例:
ApplicationContext ac=new FileSystemXmlApplicationContext("文件路徑beans.xml / applicationContext.xml");
D:\\myspringsrc\\com\\hsp\\ioc\\beans.xml 要用絕對路徑
3.XmlWebApplicationContext 當tomcat啟動的時候加載
五、bean的生命周期
為什麼總是一個生命周期當做一個重點?
Servlet -> servlet生命周期 init() destory()
① 實例化(當我們的程序加載beans.xml文件),把我們的bean(前提是scope=singleton)實例化到內存(spring 容器)
② 調用set方法設置屬性
③ 如果你實現了bean名字關注接口(BeanNameAware) 則,可以通過setBeanName獲取id號(bean的名字)
④ 如果你實現了 bean工廠關注接口,(BeanFactoryAware),則可以獲取BeanFactory
如果是單例模式bean工廠在每個bean創建的時候都創建一次。
如果是prototype模式bean工廠則只會創建一次。
⑤ 如果你實現了 ApplicationContextAware接口,則調用方法
⑥ 如果bean 和 一個後置處理器關聯,則會自動去調用 Object postProcessBeforeInitialization方法
⑦ 如果你實現InitializingBean 接口,則會調用 afterPropertiesSet
⑧ 如果自己在<bean init-method=”init” /> 則可以在bean定義自己的初始化方法.
⑨ 如果bean 和 一個後置處理器關聯,則會自動去調用 Object postProcessAfterInitialization方法
⑩ 使用我們的bean
其中非常有價值的是⑥⑨ 面向切面編程。相當於一個filter過濾器。配置關聯之後將對所有的bean有效。
11. 容器關閉
12. 可以通過實現DisposableBean 接口來調用方法 destory
13. 可以在<bean destory-method=”fun1”/> 調用定制的銷毀方法
小結: 我們實際開發中往往,沒有用的這麼的過程,常見的是:
1->2->6->9->10->11
問題:通過BeanFactory來獲取bean對象,bean的生命周期是否和Applicationcontext 是一樣嗎?
不是一樣的,bean是工廠中創建的生命周期會簡單一些: