IoC容器
Spring模塊架構(gòu)圖-IoC容器 IoC容器處于Spring模塊架構(gòu)比較核心的地位惑芭,它向上層的AOP赊堪、數(shù)據(jù)訪問(wèn)嚣潜、Web等框架提供基本的支持巷懈。
IoC容器主要要完成的功能草描,主要?jiǎng)?chuàng)建對(duì)象依賴(lài)览绿,組裝成我們需要的業(yè)務(wù)對(duì)象。
從容器角度觀察IoC容器
配置 空配置的Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
注解配置Controller
package com.netease.course.web.controller;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping(value = "/hello")
public class HelloController {
@RequestMapping(value = "/spring")
public void spring(HttpServletResponse response) throws IOException {
System.out.println("Class HelloController Method spring");
response.getWriter().write("Hello, Spring Web!!");
}
}
IoC容器 = 陶珠? ApplicationContext就是一個(gè)IoC容器挟裂。ApplicationContext屬于org.springframework.context,屬于spring-context模塊揍诽。如果只適用IoC容器的相關(guān)功能則只需要在Maven中添加spring-context模塊诀蓉。
初始化IoC 我們只是在web.xml中,的context-param添加contextConfigLocation對(duì)象和對(duì)應(yīng)xml路徑暑脆,在Listener當(dāng)中引用org.springframework.web.context.ContextLoaderListener
渠啤,這種方式是初始化Spring的一種方式。 web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:application-context.xml </param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
ClassPathXmlApplicationContext
ApplicationContext context= new ClassPathXmlApplicationContext("application-context.xml");
FileSystemXmlXmlApplicationContext
ApplicationContext context= new FileSystemXmlApplicationContext("/home/zhanpeng/Workspace/J2ee/spring-web/src/resources/application-context.xml");
Bean定義 如果定義Bean添吗,在Spring配置中沥曹,通過(guò)簡(jiǎn)單的配置文件就可以配置Bean對(duì)象。例如如下代碼
public class ScrewDriver{
public void use(){
System.out.println("Use screwDriver");
}
在Spring的配置文件中添加如下內(nèi)容碟联,這里id代表這個(gè)類(lèi)Bean對(duì)象的唯一標(biāo)識(shí)符妓美,class代表這個(gè)類(lèi)的路徑,也就是說(shuō)任何Java類(lèi)都可以生成Bean對(duì)象鲤孵,交給Spring自動(dòng)的進(jìn)行管理壶栋。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="screwDriver" class="com.netease.course.ScrewDriver" >
</bean>
</beans>
Bean使用
- 首先需要初始化容器
- 通過(guò)getBean方法,獲取對(duì)象
- 使用Bean對(duì)象的方法
//初始化容器
ApplicationContext context = new ClassPathXmlApplicationContext("application-context");
//獲取對(duì)象
ScrewDriver screwDriver = context.getBean("screwDriver",ScrewDriver.class);
//使用Bean對(duì)象
screwDriver.use();
//
Bean作用域
什么是Bean作用域普监? 強(qiáng)調(diào)Bean的有效范圍贵试,我們也需要考慮Bean是什么時(shí)候創(chuàng)建、什么時(shí)候銷(xiāo)毀的凯正。
Spring Bean作用域
singleton
prototype
以下作用域依賴(lài)Web應(yīng)用
request
session
global sesson
application
singleton 默認(rèn)的作用域就是singleton毙玻,類(lèi)似單例模式,對(duì)象只有單例
<bean id="screwDriver" class="com.netease.course.ScrewDriver"></bean>
明確定義singleton
<bean id="screwDriver" class="com.netease.course.ScrewDriver" scope="singleton"></bean>
這種方式保證對(duì)象在整個(gè)容器中是只有一個(gè)單例的廊散,保證在整個(gè)生命周期中只會(huì)創(chuàng)建出一個(gè)實(shí)例
通過(guò)代碼方式檢查單例模式
ScrewDriver screwDriver = context.getBean("screwDriver", ScrewDriver.class);
System.out.println(screwDriver);
ScrewDriver screwDriver2 = context.getBean("screwDriver", ScrewDriver.class);
System.out.println(screwDriver2);
執(zhí)行結(jié)果
com.netease.course.ScrewDriver@12405818
com.netease.course.ScrewDriver@12405818
prototype 每次引用都需要?jiǎng)?chuàng)建對(duì)象桑滩,就使用prototype
,比如兩次飲用時(shí)需要保存一些狀態(tài)允睹,但是在下次引用時(shí)并不需要該狀態(tài)帶入到實(shí)例中施符。
<bean id="screwDriver" class="com.netease.course.ScrewDriver" scope="prototype"></bean>
每次引用創(chuàng)建一個(gè)實(shí)例
通過(guò)代碼方式檢查多次引用
ScrewDriver screwDriver = context.getBean("screwDriver", ScrewDriver.class);
System.out.println(screwDriver);
ScrewDriver screwDriver2 = context.getBean("screwDriver", ScrewDriver.class);
System.out.println(screwDriver2);
執(zhí)行結(jié)果
com.netease.course.ScrewDriver@12405818
com.netease.course.ScrewDriver@314c508a
每次引用創(chuàng)建一個(gè)實(shí)例
Web場(chǎng)景下的Bean作用域
request request scope,作為訪問(wèn)者訪問(wèn)Web服務(wù)就是為一個(gè)request scope擂找,在請(qǐng)求處理過(guò)程中戳吝,需要?jiǎng)?chuàng)建bean,但是在另外一個(gè)訪問(wèn)Web服務(wù)的請(qǐng)求時(shí)贯涎,創(chuàng)建另外的Bean听哭。
session session scope包含多個(gè)request scope,表示某個(gè)用戶(hù)在訪問(wèn)過(guò)程中,會(huì)共享一些Bean對(duì)象陆盘,例如sessionBean普筹,比如保存用戶(hù)的會(huì)話信息或者狀態(tài)信息。在用戶(hù)沒(méi)有退出的時(shí)候隘马,這些Bean都是有效的太防。多個(gè)Session的話會(huì)使用不同的sessionBean。
application 在整個(gè)應(yīng)用狀態(tài)下會(huì)共享某個(gè)單獨(dú)的Bean酸员,比如一些ServiceBean蜒车。
Bean生命周期回調(diào) 有了Bean的作用域,就可以控制Bean的創(chuàng)建和銷(xiāo)毀幔嗦,但并不知道我們?cè)趧?chuàng)建時(shí)可以做那些事情酿愧,也不知道銷(xiāo)毀時(shí)可以做那些事情。一般我們?cè)诰帉?xiě)一些和資源打交道的服務(wù)和功能的時(shí)候邀泉,很有可能在創(chuàng)建或者銷(xiāo)毀的時(shí)候做些額外的事情嬉挡,比如當(dāng)創(chuàng)建時(shí)申請(qǐng)資源:申請(qǐng)線程池或者申請(qǐng)文件系統(tǒng)資源,當(dāng)銷(xiāo)毀時(shí)汇恤,我們對(duì)資源進(jìn)行釋放庞钢。
- 創(chuàng)建
- 申請(qǐng)資源
- 銷(xiāo)毀
- 釋放資源
Spring生命周期回調(diào)
- 創(chuàng)建
public interface InitializingBean{
void afterPropertiesSet() throws Exception;
}
在初始化結(jié)束后(在Spring對(duì)該對(duì)象設(shè)置完成屬性后)添加一些執(zhí)行內(nèi)容。
我們可以通過(guò)簡(jiǎn)單的xml方式配置
<bean id="screwDriver" class="com.netease.course.ScrewDriver" init-method="init"></bean>
xml方式所對(duì)應(yīng)的初始化代碼如下:
package com.netease.course;
import javax.annotation.Resource;
public class ScrewDriver {
public void init()
{
System.out.println("Init screwDriver");
}
}
- 銷(xiāo)毀
public interface DisposableBean{
void destroy() throws Exception;
}
```我們可以通過(guò)簡(jiǎn)單的xml方式配置
<bean id="screwDriver" class="com.netease.course.ScrewDriver" destroy-method="cleanup"></bean>
xml方式所對(duì)應(yīng)的初始化代碼如下:
package com.netease.course; import javax.annotation.Resource;
public class ScrewDriver { public void cleanup() { System.out.println("Destroy screwDriver"); } }
##通過(guò)代碼查看回調(diào)情況
package com.netease.course;
import javax.annotation.Resource;
public class ScrewDriver {
private String color = "red";
public void use() {
// System.out.println("Use " + color + " screwdriver"); }
public void setColor(String color)
{
this.color = color;
}
public void init()
{
System.out.println("Init " + this);
}
public void cleanup()
{
System.out.println("Destroy " + this);
}
}
執(zhí)行結(jié)果因谎,并沒(méi)有看到銷(xiāo)毀Bean對(duì)象
Init com.netease.course.ScrewDriver@25359ed8 use red screwdriver
這是由于我們并沒(méi)有有效的關(guān)閉容器基括,導(dǎo)致容器沒(méi)有辦法調(diào)用到destory-method,這里需要手動(dòng)添加手動(dòng)關(guān)閉容器蓝角。ApplicationContext本身并不支持關(guān)閉,我們需要把它強(qiáng)制轉(zhuǎn)化到支持close的方式并close饭冬。
**注意**:筆者這里也沒(méi)有調(diào)用到銷(xiāo)毀使鹅。
轉(zhuǎn)自:https://my.oschina.net/hava/blog/757200