1. 程式人生 > 程式設計 >Spring框架花式建立Bean的n種方法(小結)

Spring框架花式建立Bean的n種方法(小結)

常用的從容器中獲取bean例項使用這樣的方式:

@Test
	public void test() {
		Persion p = (Persion) ioc.getBean("p1");
		System.out.println(p);
	}

常用的在容器中配置元件使用這樣的方式:

	<bean id="p1" class="com.gql.bean.Persion">
		<property name="name" value="張三"></property>
		<property name="age" value="18"></property>
		<property name="email" value="[email protected]"></property>
		<property name="gender" value="男"></property>
	</bean>

下面的實驗介紹一些Spring容器中註冊元件物件的其他方法。

實驗1:根據bean的型別從ioc容器中獲取例項

@Test
	public void test01() {
		Persion p = ioc.getBean(Persion.class);
		System.out.println(p);
	}

這種方法查詢的好處是不需要型別轉換,但是如果ioc容器中要找的bean有多個,使用這種方法查詢就會報錯。可以改用下面的方式:

	@Test
	public void test01() {
		Persion p = ioc.getBean("p1",Persion.class);
		System.out.println(p);
	}

實驗2:通過有參構造器為bean的屬性賦值

需要提前在bean中新增有參構造器,才能進行下面的測試。

	<bean id="p2" class="com.gql.bean.Persion">
		<constructor-arg name="name" value="李四"></constructor-arg>
		<constructor-arg name="age" value="22"></constructor-arg>
		<constructor-arg name="email" value="[email protected]"></constructor-arg>
		<constructor-arg name="gender" value="男"></constructor-arg>
	</bean>

使用這種有參構造器為bean的屬性賦值,可以省略name,但是value的順序必須與bean中的順序一致。(若再使用index和type進行索引,可以不按順序)

通過名稱空間為bean賦值:

新增p名稱空間標籤頭:xmlns:p=“http://www.springframework.org/schema/p”

<bean id="p4" class="com.gql.bean.Persion" p:name="小王" p:age="22"
		p:gender="男" p:email="[email protected]"></bean>

實驗3:為各種屬性賦值

引用型別、集合型別、級聯型別。

如題,給出一個賦值的Bean物件,為其在容器中註冊。此時所有複雜的賦值都在property標籤體內。

public class Persion {
	private String name;
	private String gender;
	private Integer age;
	private String email;

	private Car car;

	private List<Book> book;

	private Map<String,Object> maps;

	private Properties properties;
	//省略setter與getter方法
}

普通屬性賦值:

<!-- 普通屬性賦值 -->
		<property name="name" value="張三"></property>
		<property name="gender" value="男"></property>
		<property name="age" value="20"></property>
		<property name="email">
			<null />
		</property>

引用型別賦值:

	<bean id="p1" class="com.gql.bean.Persion">
		<!-- 引用外部bean -->
		<!-- <property name="car" ref="c1"></property> -->
		<!-- 引用內部bean(內部bean不能被獲取到) -->
		<property name="car">
			<bean class="com.gql.bean.Car">
				<property name="carName" value="自行車"></property>
				<property name="color" value="黑色"></property>
				<property name="price" value="400"></property>
			</bean>
		</property>
	</bean>
	
	<bean id="c1" class="com.gql.bean.Car">
		<property name="carName" value="寶馬"></property>
		<property name="color" value="白色"></property>
		<property name="price" value="30000"></property>
	</bean>

集合型別賦值:

list

<bean id="p1" class="com.gql.bean.Persion">
		<property name="book">
			<list>
				<bean class="com.gql.bean.Book" p:bookName="西遊記" p:author="吳承恩"></bean>
				<ref bean="book01" />
			</list>
		</property>
	</bean>
	
	<bean id="book01" class="com.gql.bean.Book">
		<property name="bookName" value="水滸傳"></property>
		<property name="author" value="施耐庵"></property>
	</bean>

map

<property name="maps">
			<map>
				<entry key="k01" value="v01"></entry>
				<entry key="k02" value="v02"></entry>
				<entry key="k03" value-ref="book01"></entry>
				<entry key="k04">
					<bean class="com.gql.bean.Car">
						<property name="carName" value="捷豹"></property>
						<property name="color" value="紅色"></property>
						<property name="price" value="50000"></property>
					</bean>
				</entry>
			</map>
		</property>

properties

	<property name="properties">
			<props>
				<prop key="username">root</prop>
				<prop key="password">123456</prop>
			</props>
		</property>

實驗4:通過繼承實現bean配置資訊的重用

下面的程式碼中p4繼承了p3,需要改動的屬性在property標籤中修改即可,其餘的全部原樣繼承。

<bean id="p3" class="com.gql.bean.Persion">
		<property name="name" value="張三"></property>
		<property name="age" value="20"></property>
		<property name="gender" value="男"></property>
		<property name="email" value="[email protected]"></property>
	</bean>

	<bean id="p4" parent="p3">
		<property name="name" value="李四"></property>
	</bean>

實驗5:單例項singleton和多例項prototype

單例項singleton 多例項prototype
容器啟動時建立好物件並儲存在容器中 獲取Bean時才會建立這個物件
②呼叫初始化方法 ②呼叫初始化方法
容器關閉時呼叫銷燬方法 容器銷燬時不呼叫銷燬方法
任何時間獲取都是獲取之前建立好的那個物件 每次獲取都會建立一個新的物件

詳情可參照部落格:通過工廠建立Bean的三種方式

實驗6:建立帶有生命週期的Bean

ioc容器中註冊的元件:

  • 單例項:容器啟動的時候就會建立好,容器關閉也會銷燬建立的bean。
  • 多例項:獲取的時候才建立。

可以為bean自定義一些生命週期方法,spring在建立或銷燬的時候就會呼叫指定的方法。

(1)單例項Singleton測試

在Book類中建立方法:

package com.gql.bean;
public class Book {
	private String bookName;
	private String author;

	public void myInit() {
		System.out.println("Book的初始化方法...");
	}

	public void myDestory() {
		System.out.println("Book的銷燬方法...");
	}

	public Book() {
		super();
		// TODO Auto-generated constructor stub
		System.out.println("Book建立...");
	}
}

在xml中註冊元件:

<bean id="book01" class="com.gql.bean.Book" destroy-method="myDestory" init-method="myInit"></bean>

測試:

在ApplicationContext中沒有close方法,需要將容器型別轉換為ConfigurableApplicationContext 。

public class IoCTest {
	ConfigurableApplicationContext ioc = new ClassPathXmlApplicationContext("ApplicationContext.xml");

	@Test
	public void test10() {
		System.out.println("容器關閉了");
		ioc.close();
	}
}

Spring框架花式建立Bean的n種方法(小結)

(2)多例項prototype測試

只需要改變xml中註冊元件為多例項:

<bean id="book01" class="com.gql.bean.Book" destroy-method="myDestory" init-method="myInit" scope="prototype"></bean>

仍然使用上面的方法進行測試:

Spring框架花式建立Bean的n種方法(小結)

可以看到容器的建立銷燬一系列都沒有進行,這是因為多例項在獲取bean的時候才建立例項。

多例項測試中增加獲取bean:

	@Test
	public void test10() {
		Object bean = ioc.getBean("book01");
		System.out.println(bean);
		System.out.println("容器關閉了");
		ioc.close();
	}

Spring框架花式建立Bean的n種方法(小結)

測試結果中,成功建立了例項,但是容器關閉並沒有銷燬Bean。

實驗7:測試Bean的後置處理器

後置處理器有一點代理物件的意思,使用後置處理器,Bean的生命週期變成下面的樣子:

容器啟動—>後置處理器Before—>初始化方法—>後置處理器After—>容器關閉(呼叫銷燬方法)

不管有沒有初始化方法,後置處理器都會預設其有,繼續工作。

後置處理器:

package com.gql.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
 * 1.編寫後置處理器 
 * 2.將後置處理器註冊在配置檔案
 * @author guoqianliang
 *
 */
public class MyBeanPostProcessor implements BeanPostProcessor {

	/**
	 * 初始化前呼叫
	 */
	@Override
	public Object postProcessBeforeInitialization(Object bean,String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("Before:" + beanName + "將要呼叫初始化方法了..." + bean);
		return bean;
	}

	/**
	 * 初始化後呼叫
	 */
	@Override
	public Object postProcessAfterInitialization(Object bean,String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("After:" + beanName + "初始化方法呼叫完了" + bean);
		return bean;
	}
}

將後置處理器註冊在配置檔案:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<bean id="book01" class="com.gql.bean.Book" destroy-method="myDestory" init-method="myInit" scope="singleton"></bean>
	
	<!-- 後置處理器:可以在bean的初始化前後呼叫方法 -->
	<bean id="beanPostProcessor" class="com.gql.bean.MyBeanPostProcessor"></bean>
</beans>

測試:

@Test
	public void test11() {
		Object bean = ioc.getBean("book01");
		System.out.println("容器關閉了");
		ioc.close();
	}

Spring框架花式建立Bean的n種方法(小結)

實驗8:引用外部檔案

在Spring中bean預設都是單例項的,而資料庫作為單例項是最好不過的,一個專案就是一個連線池,連線池裡面管理很多連線,連線是直接從連線池中拿。可以讓Spring幫我們建立連線池物件,管理連線池。

註冊連線池第一代

在配置中註冊連線池:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="root"></property>
		<property name="password" value="Hudie"></property>
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
	</bean>

測試:

@Test
	public void test12() throws SQLException {
		// 從容器中拿到連線
		// DataSource bean = (DataSource) ioc.getBean("dataSource");
		DataSource bean2 = ioc.getBean(DataSource.class);
		System.out.println(bean2.getConnection());
	}

成功獲取到了這個連線:

Spring框架花式建立Bean的n種方法(小結)

註冊連線池第二代

在config包下建立一個dbconfig.properties用來儲存資料庫連線資訊。

為了防止配置檔案中的key與Spring自己的關鍵字衝突。可以為key加一個字首,業內通用的做法是使用jabc.xxx

jdbc.username:root
jdbc.password:Hudie
jdbc.jdbcUrl:jdbc:mysql://localhost:3306/test
jdbc.driverClass:com.mysql.jdbc.Driver

註冊資料庫連線池:

	<bean id="dataSource"
		class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		<property name="driverClass" value="${jdbc.driverClass}"></property>
	</bean>

測試:

@Test
	public void test12() throws SQLException {
		DataSource bean2 = ioc.getBean(DataSource.class);
		System.out.println(bean2.getConnection());
	}

Spring框架花式建立Bean的n種方法(小結)

到此這篇關於Spring框架花式建立Bean的n種方法的文章就介紹到這了,更多相關Spring 建立Bean內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!