1. 程式人生 > >Spring IOC 建立bean例項的方式

Spring IOC 建立bean例項的方式

據我所知,建立bean例項的方式有4種方式~

下面我會一一寫出來這4種方式~

第一種:xml檔案中有bean的配置,而且這個bean所對應的java類中存在一個無參構造器,那麼這個時候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"

	xsi:schemaLocation="http://www.springframework.org/schema/beans

           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

           http://www.springframework.org/schema/context

           http://www.springframework.org/schema/context/spring-context-3.2.xsd">
  <bean name="stu" class="com.x.spring.test1.Student">
      <property name="name">
          <value>張三</value>
      </property>
  </bean>
  
</beans>
這就是一個bean例項~,我前幾篇就是這樣建立bean例項的,我這裡就不多說了~接下來看第二種方式

第二種:通過工廠類獲得例項(工廠類實現了介面FactoryBean<?>)

注意:spring中的PropertyPlaceholderConfigurer類的使用,在htmlsingle中直接搜尋類名即可

例如:

工廠類ConnectionFactory實現指定介面並且實現介面中的三個抽象方法:

public class ConnectionFactory implements FactoryBean<Connection>{

	private String driver;
	private String url;
	private String username;
	private String password;

	public String getDriver() {
		return driver;
	}

	public void setDriver(String driver) {
		this.driver = driver;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}


    //連線
	@Override
	public Connection getObject() throws Exception {
		Class.forName(driver);
		Connection conn = 
			DriverManager.getConnection(url,username,password);
		return conn;
	}

	@Override
	public boolean isSingleton() {
		// TODO Auto-generated method stub
		return false;
	}
	
	@Override
	public Class<Connection> getObjectType() {
		// TODO Auto-generated method stub
		return Connection.class;
	}
}
注意:一定要加上這個jar包-mysql-connector-java-5.1.18-bin.jar,這個jar包我在Hibernate裡面就用過,這是連線資料庫的~如圖:



配置檔案factory.xml:

<?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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    
     
	
	<!-- 通過conn拿到的是對應的這個工廠類所生產的產品物件 -->
	<!-- 造成這種現象的原因:因為這個類ConnectionFactory是一個工廠類,所以我們用名字conn在容器中拿物件的時候,
    	拿到並不是這個工廠類物件,而是這個工廠類物件呼叫完工廠方法後所返回的物件. -->
	<bean name="conn" class="com.x.spring.test3.factory.ConnectionFactory">
	    <!-- 從一個配置檔案中以key—value的形式拿value -->
		<property name="url" value="${url}"></property>
		<property name="driver" value="${driver}"></property>
		<property name="username" value="${username}"></property>
		<property name="password" value="${password}"></property>
	</bean>
	
     <!-- 
    	下面配置的這個類,可以自動的幫我們去讀取指定的properties檔案的
    	內容,檔案中用key-value的形式存放資料,讀完之後我們就可以用
    	${key}這種形式去拿檔案中的value值了。
    	classpath指的是從src下面找.
      -->
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	  <property name="locations" value="classpath:mysql.properties"/>
	</bean>
</beans>
還需要properties檔案~我放在src目錄下面~
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssh
username=root
password=root
測試類FactoryTest:
public class FactoryTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		//在xml中配置工廠類,然後通過這個工廠類獲得工廠生產的例項
		try {
			String path = "com/x/spring/test3/factory/factory.xml";
			ApplicationContext container = 
					new ClassPathXmlApplicationContext(path);
			Connection conn = (Connection)container.getBean("conn");
			System.out.println(conn);
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}
效果圖:


注意: 通過conn拿到的並不是要拿到工廠類的物件,而是對應的這個工廠類所生產的產品物件~這一點要記住

好了,第二種方式寫完了,開始第三種方式~

第三種:通過例項工廠獲得例項(不需要實現或者繼承任何介面或者父類)

 注意spring中的PropertyPlaceholderConfigurer類的使用,在htmlsingle中直接搜尋類名即可

例如:

一個普通的工程類ConnectionFactory:

public class ConnectionFactory {

	private String driver;
	private String url;
	private String username;
	private String password;
	
	public Object getConnection() throws Exception {
		Class.forName(driver);
		Connection conn = 
			DriverManager.getConnection(url,username,password);
		return conn;
	}
	public String getDriver() {
		return driver;
	}

	public void setDriver(String driver) {
		this.driver = driver;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}
這個類沒有繼承和實現任何介面或類

配置檔案instanceFactory.xml:

<?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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.2.xsd">
   <span style="color:#ff0000;"><!-- 讀取properties檔案 --></span>
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations" value="classpath:mysql.properties"/>
	</bean>
    
    <bean name="factory" class="com.x.spring.test3.instanceFactory.ConnectionFactory">
   		<property name="url" value="${url}"></property>
		<property name="driver" value="${driver}"></property>
		<property name="username" value="${username}"></property>
		<property name="password" value="${password}"></property>
    </bean>
    
    <span style="color:#ff0000;"> <!-- 
		將來通過這個conn來拿物件,拿到的是名字為factory的工廠類呼叫完
		名字為getConnection方法之後所返回的物件。
	 --></span>
    <bean name="conn" factory-bean="factory" factory-method="getConnection"></bean>
    
</beans>
properties檔案上面有程式碼,我就不貼了~

測試類InstanceTest:

public class InstanceTest {

	public static void main(String[] args) {
		//通過例項工廠獲得例項(不需要實現或者繼承任何介面或者父類)
		try {
			String path = "com/x/spring/test3/instanceFactory/instanceFactory.xml";
			ApplicationContext container = 
					new ClassPathXmlApplicationContext(path);
			Connection conn = (Connection)container.getBean("conn");
			System.out.println(conn);
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

效果圖:



好了,第三種方式也說完了~接下來第四種~

第四種:通過靜態工廠獲得例項

例如:含義靜態方法的工廠類ConnectionFactory

public class ConnectionFactory {
	private static String driver = "com.mysql.jdbc.Driver";
	private static String url = "jdbc:mysql://localhost:3306/ssh";
	private static String username = "root";
	private static String password = "root";
	
	public static Object getConnection() throws Exception {
		Class.forName(driver);
		Connection conn = 
			DriverManager.getConnection(url,username,password);
		return conn;
	}
}
有沒有覺得這個很熟悉~不錯,這就是properties檔案的一些配置屬性~

這就可以不用寫properties檔案了~

配置檔案staticFactory.xml:

<?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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.2.xsd">
     <!-- 這樣配置一定要求getConnection方法是靜態方法 -->
    <bean name="conn" class="com.x.spring.test3.staticFactory.ConnectionFactory" factory-method="getConnection"></bean>
    
</beans>
測試類:
public class StaticTest {

	public static void main(String[] args) {
		//通過靜態工廠獲得例項
		try {
			String path = "com/x/spring/test3/staticFactory/staticFactory.xml";
			ApplicationContext container = 
					new ClassPathXmlApplicationContext(path);
			Connection conn = (Connection)container.getBean("conn");
			System.out.println(conn);
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

執行效果:



有沒有覺得這三種方式的效果圖都差不多~

就後面的一些數字不一樣~

看來這三種方式通過conn拿到的並不是要拿到工廠類的物件,而是對應的這個工廠類所生產的產品物件~這一點要記住