【spring系列】- Spring的FactoryBean的基本認識
阿新 • • 發佈:2019-02-09
FactoryBean:工廠Bean
IOC容器內部一種特殊的Bean,主要作用就是管理內部的Bean例項物件(單例/原型物件),扮演類似工廠的角色
特點:
通過Bean名稱只能獲取其生產的物件,而不是FactoryBean本身,如果需要獲取FactoryBean本身可以通過“&Bean名稱”的形式獲取
測試:
首先構建一個FactoryBean:UserFactoryBean
package com.zhiwei.factoryBean; import org.springframework.beans.factory.FactoryBean; public class UserFactoryBean implements FactoryBean<User> { /** * FacotryBean生產的物件 */ @Override public User getObject() throws Exception { return new User(); } @Override public Class<User> getObjectType() { return User.class; } /** * 判斷FactoryBean管理的物件是否是單例物件 */ @Override public boolean isSingleton() { return false; } }
輔助類:User
package com.zhiwei.factoryBean; public class User { private String name; private int age; public User(){ this("zhangsan",20); } public User(String name,int age){ this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [name=" + name + ", age=" + age + "]"; } }
Spring配置檔案:
<!-- 普通的FactoryBean -->
<bean id="userFactoryBean" class="com.zhiwei.factoryBean.UserFactoryBean"/>
測試程式碼:
ApplicationContext ac = new ClassPathXmlApplicationContext("com/zhiwei/factoryBean/applicationContext.xml"); //---------獲取FactoryBean生產的物件 Object obj = ac.getBean("userFactoryBean"); System.err.println("userFactoryBean物件型別:"+obj.getClass().getName()); //--------獲取factoryBean本身 obj = ac.getBean("&userFactoryBean"); System.err.println("&userFactoryBean物件型別:"+obj.getClass().getName()); //----------判斷FactoryBean管理的是否是單例物件 System.err.println("userFactoryBean管理單例物件:"+((UserFactoryBean)obj).isSingleton());
控制檯日誌:
userFactoryBean物件型別:com.zhiwei.factoryBean.User
&userFactoryBean物件型別:com.zhiwei.factoryBean.UserFactoryBean
userFactoryBean管理單例物件:false
FactoryBean的用途:
一般進行Spring和其他的ORM框架整合時一般會用到FactoryBean,例如整合Hibernate使用的LocalSessionFactoryBean,整合mybatis使用的SqlSessionFactoryBean等,一般這些FactoryBean主要用於對一些配置資訊的管理,例如資料來源
單例FactoryBean應用:
定義DatabaseFactoryBean:
package com.zhiwei.factoryBean;
import org.springframework.beans.factory.FactoryBean;
/**
* 單例模式:FactoryBean的應用
* @author Yang ZhiWei
*
*/
public class DatabaseFactoryBean implements FactoryBean<DatabaseConfig>{
private DatabaseConfig databaseConfig;
public DatabaseConfig getDatabaseConfig() {
return databaseConfig;
}
public void setDatabaseConfig(DatabaseConfig databaseConfig) {
this.databaseConfig = databaseConfig;
}
/**
* 單例模式返回規定的物件
*/
@Override
public DatabaseConfig getObject() throws Exception {
if(null == databaseConfig){
synchronized (databaseConfig) {
if(null == databaseConfig){
databaseConfig = new DatabaseConfig();
}
}
}
return databaseConfig;
}
@Override
public Class<User> getObjectType() {
return User.class;
}
/**
* FactoryBean管理單例物件,返回true
*/
@Override
public boolean isSingleton() {
return true;
}
}
輔助類:DatabaseConfig
package com.zhiwei.factoryBean;
/**
* 資料庫配置資訊
* @author Yang ZhiWei
*
*/
public class DatabaseConfig {
private String databaseName;
private String ip;
private String port;
private String userName;
private String passwd;
public String getDatabaseName() {
return databaseName;
}
public void setDatabaseName(String databaseName) {
this.databaseName = databaseName;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
@Override
public String toString() {
return "DatabaseConfig [databaseName=" + databaseName + ", ip=" + ip + ", port=" + port + ", userName="
+ userName + ", passwd=" + passwd + "]";
}
}
Spring配置檔案:
<!-- 配置資料來源 -->
<bean id="dataSource" class="com.zhiwei.factoryBean.DatabaseConfig">
<property name="databaseName" value="test"/>
<property name="ip" value="127.0.0.1"/>
<property name="port" value="3306"/>
<property name="userName" value="userName"/>
<property name="passwd" value="test"></property>
</bean>
<!-- 配置資料庫訪問FactoryBean -->
<bean id="databaseFactoryBean" class="com.zhiwei.factoryBean.DatabaseFactoryBean">
<property name="databaseConfig" ref="dataSource"/>
</bean>
測試程式碼:
//-----------------------使用資料庫的FactoryBean
DatabaseConfig databaseConfig = (DatabaseConfig) ac.getBean("databaseFactoryBean");
System.out.println(databaseConfig);
控制檯日誌:
DatabaseConfig [databaseName=test, ip=127.0.0.1, port=3306, userName=userName, passwd=test]