前言
我們知道spring架構的核心就是IOC容器了,那麼IOC容器主要的作用就是建立對象和處理對象之間的依賴關系。本文主要講解IOC容器建立對象的三種方式。
建立對象的三種方式
1) 調用無參數構造器
2) 帶參數構造器
3) 工廠建立對象
包括:3.1 工廠類,靜态方法建立對象
3.2 工廠類,非靜态方法建立對象
1.調用無參數的構造器
具體如下:
User.java
public class User {
private int id;
private String name;
public User() {
super();
System.out.println("------User對象建立【無參數構造器】------");
}
public User(int id, String name) {
System.out.println("-----User對象建立【帶參數構造器】--------");
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + "]";
}
}
Bean.xml配置如下:
<!-- 1. 預設無參數構造器 -->
<bean id="user1" class="com.nwpu.geeker.User"></bean>
測試:
// 測試:對象建立
@Test
public void testIOC() throws Exception {
// 建立IOC容器對象
ApplicationContext ac = new ClassPathXmlApplicationContext("com/nwpu/geeker/bean.xml");
// 擷取容器中的對象
User user = (User) ac.getBean("user");
System.out.println(user);
}
2.帶參數構造器建立對象
例如:上面的user.java 有帶參的構造器,參數清單為(int,string).一般依賴注入對象的時候用的比較多。
配置如下:
<!-- 2. 帶參數構造器 -->
<bean id="user2" class="com.nwpu.geeker..User">
<constructor-arg index="0" type="int" value="100"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="Jack"></constructor-arg>
</bean>
其中index屬性表示參數的位置。Type表示類型,value表示指派,還有一個ref屬性下面将會介紹,表示可以引用IOC容器建立好的(已存在的)對象。
配置如下:
<!-- 定義一個字元串,值是"Jack" ; String s = new String("jack")-->
<bean id="str" class="java.lang.String">
<constructor-arg value="Jacks"></constructor-arg>
</bean>
<bean id="user3" class="com.nwpu.geeker.User">
<constructor-arg index="0" type="int" value="100"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" ref="str"></constructor-arg>
</bean>
ref屬性引用的就是IOC容器建立對象的id屬性值。
3.通過工廠類建立對象
3.1 通過執行個體化工廠,非靜态方法建立對象
先建立工廠javaBean
// 工廠,建立對象
public class ObjectFactory {
// 執行個體方法建立對象
public User getInstance() {
return new User(100,"工廠:調用執行個體方法");
}
// 靜态方法建立對象
public static User getStaticInstance() {
return new User(101,"工廠:調用靜态方法");
}
}
配置檔案:
<!-- # 3.1 工廠類,執行個體方法 -->
<!-- 先建立工廠 -->
<bean id="factory" class="com.nwpu.geeker.ObjectFactory"></bean>
<!-- 在建立user對象,用factory方的執行個體方法 -->
<bean id="user4" factory-bean="factory" factory-method="getInstance"></bean>
其中: factory-bean=”factory”指定工廠。factory-method=”getInstance”指定工廠的哪個方法。
3.2 工廠類: 靜态方法建立對象
<bean id="user" class="com.nwpu.geeker.ObjectFactory" factory-method="getStaticInstance"></bean>
class 指定的就是工廠類型,這裡是和上面配置不同的地方。
factory-method 一定是工廠裡面的“靜态方法”
建立對象的細節問題
1) 對象建立: 單例/多例
在bean.xml配置檔案中,配置scope=”singleton”,為單例建立對象,如果不配置,預設也是單例方式。主要應用于service/dao層還有一些utils工具類等隻需要在伺服器啟動時初始化一次即可。
scope=”prototype”,表示多例方式建立對象,也就是當使用者需要使用這個對象時即建立對象,在ssh項目整合中主要應用于Action對象。這種方式一般在伺服器啟動時不會建立對象,在每次使用才建立。
2) 什麼時候建立?上面其實已經說了
scope=”prototype” 在用到對象的時候,才建立對象。(在ioc容器初始化之後)
scope=”singleton” 在伺服器啟動時候(容器初始化之前), 就已經建立了bean,且整個應用隻有一個。
3)是否延遲建立
lazy-init=”false” 預設為false, 不延遲建立,即在啟動時候就建立對象
lazy-init=”true” 延遲初始化, 在用到對象的時候才建立對象
(隻對單例有效)因為多例本來就是通路對象時才建立。
4) 建立對象之後,初始化/銷毀
init-method=”init_user” 【對應對象的init_user方法,在對象建立好之後執行 】
destroy-method=”destroy_user” 【在調用容器對象的destroy方法時候執行,(容器用實作類)】
public class User {
private int id;
private String name;
public User() {
super();
System.out.println("------User對象建立------");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void init_user() {
System.out.println("建立對象之後,初始化");
}
public void destroy_user() {
System.out.println("IOC容器銷毀,user對象回收!");
}
}
測試:
@Test
public void testIOC() throws Exception {
// 得到IOC容器對象 【用實作類,因為要調用銷毀的方法】
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("com/nwpu/geeker/applicationContext.xml");
System.out.println("-----容器建立-----");
// 從容器中擷取bean
User user1 = (User) ac.getBean("user");
User user2 = (User) ac.getBean("user");
System.out.println(user1);
System.out.println(user2);
// 銷毀容器對象
ac.destroy();
}
@Test
public void test() throws Exception {
// 容器對象
ApplicationContext ac = new ClassPathXmlApplicationContext("com/nwpu/geeker/applicationContext.xml");
System.out.println("-----容器建立完成-----");
User user1 = (User) ac.getBean("user1");
}