控制反轉(IOC--Inversion of control)
所謂控制反轉就是應用本身不負責依賴對象的創(chuàng)建及維護,依賴對象的創(chuàng)建及維護是由外部容器負責的谭胚。這樣控制權就由應用轉移到了外部容器没陡,控制權的轉移就是所謂反轉
Spring的控制反轉:
把對象的創(chuàng)建遭贸、初始化隐绵、銷毀等工作交給spring容器來做。由spring容器控制對象的生命周期呀页。
步驟:
A. 啟動spring容器
1、在類路徑下尋找配置文件來實例化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(" xxx.xml");
可以在整個類路徑中尋找xml文件
* 通過這種方式加載拥坛。需要將spring的配置文件放到當前項目的classpath路徑下
* classpath路徑指的是當前項目的src目錄蓬蝶,該目錄是java源文件的存放位置。
例如:
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
2渴逻、在文件系統(tǒng)路徑下尋找配置文件來實例化容器
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});
Spring的配置文件可以指定多個疾党,可以通過String數(shù)組傳入。
注:經(jīng)常用第一種方法啟動容器
B. 從spring容器中提取對象
別名
通過這樣的配置惨奕,可以達到在一個地方命名雪位,在多個地方使用不同的名字的效果。
創(chuàng)建對象三種的方式
無參構造函數(shù)
無參構造函數(shù)
<bean id="helloWorld" class="com.hw.entity.HelloWorldFactory" >
</bean>
靜態(tài)工廠
public class HelloWorld {
public void hello() {
System.out.println("哈哈");
}
}
--------------------------------------------
public class HelloWorldFactory {
public static HelloWorld getFactory() {
return new HelloWorld();
}
}
---------------------------------------------------
<bean id="helloWorld2" class="com.hw.entity.HelloWorldFactory" factory-method="getFactory"></bean>
@Test
public void test001() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld hello = (HelloWorld) ac.getBean("helloWorld2");
hello.hello();
}
}
實例工廠
public class HelloWorld {
public void hello() {
System.out.println("哈哈");
}
}
public class HelloWorldFactory {
public HelloWorld getFactory() {
return new HelloWorld();
}
}
<bean id="helloWorld" class="com.hw.entity.HelloWorldFactory" ></bean>
<bean id="helloWorld3" factory-bean="helloWorld" factory-method="getFactory"></bean>
@Test
public void test001() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld hello = (HelloWorld) ac.getBean("helloWorld2");
hello.hello();
}
}
Bean的作用域 ,對象的scope
五種:
1.singleton:單例模式
singleton(默認值)
在每個Spring IoC容器中一個bean定義只有一個對象實例(共享)梨撞。
默認情況下會在容器啟動時初始化bean雹洗,但我們可以指定Bean節(jié)點的lazy-init=“true”來延遲初
始化bean,這時候卧波,只有第一次獲取bean會才初始化bean时肿。如:
<bean id="xxx" class="com.xxx.xxx" lazy-init="true"/>
如果想對所有bean都應用延遲初始化,可以在根節(jié)點beans設置default-lazy-init=“true“港粱,
2.prototype:原型模式
允許bean可以被多次實例化(使用一次就創(chuàng)建一個實例) . Spring不能對一個prototype bean的
整個生命周期負責.這就意味著清楚prototype作用域的對象并釋放任何prototype bean所持有的
昂貴資源都是客戶端的責任螃成。
3.request
4.session
5.global session
初始化bean時機
Spring默認在啟動時將所有singleton bean提前進行實例化。提前實例化意味著作為初始化的一
部分查坪,ApplicationContext會自動創(chuàng)建并配置所有的singleton bean.通常情況下這是件好事寸宏。
因為這樣在配置中有任何錯誤能立即發(fā)現(xiàn)。
Lazy-init 為false,spring容器將在啟動的時候報錯(比較好的一種方式)
Lazy-init 為true,spring容器將在調用該類的時候出錯偿曙。
如果scope為prototype, Lazy-init將失去作用
init氮凝、destroy
Spring初始化bean或銷毀bean時,有時需要作一些處理工作望忆,因此spring可以在創(chuàng)建和拆卸bean的時候調用bean
的兩個生命周期方法罩阵。
public class HelloWorld {
public HelloWorld() {
System.out.println("new instance");
}
public void init() {
System.out.println("init");
}
public void destroy() {
System.out.println("detroy");
}
public void hello() {
System.out.println("哈哈");
}
}
-----------------------------------------------
<bean id="helloWorld" class="com.hw.entity.HelloWorld"
init-method="init" destroy-method="destroy" scope="prototype">
</bean>
---------------------------------------------------------
@Test
public void test001() {
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
helloWorld.hello();
ClassPathXmlApplicationContext applicationContext =
(ClassPathXmlApplicationContext)context;
applicationContext.close();
}