Spring中BeanFactory的物件註冊與依賴繫結方式
阿新 • • 發佈:2018-11-15
概念
- BeanFactory是spring的基礎型別IOC容器,提供完整的IOC服務支援
- 預設採用延遲初始化策略,當客戶端物件訪問受管物件時,才對其進行初始化和依賴注入
理解
- BeanFactory將每個物件看做一個bean,通過配置檔案,編碼,註解等方式獲取組裝這個bean的
零件,最終對使用者提供一個獲取bean的介面
- 使用者不用關心bean如何組裝
- BeanFactory簡化並接管了物件間複雜的依賴繫結關係,由業務物件自己去new,去拉業務物件,變成了BeanFactory來推送業務物件,使用者只需使用簡單的註解就可以獲取物件
BeanFactory有三種方式來管理業務物件的註冊和依賴繫結
程式碼如下:
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.Serializable; /** * @Author: Lisa * @Date: 2018/11/12 14:15 */ @Component public class Student implements Serializable { private static final long serialVersionUID = 3547480842866045450L; @Value(value = "12") private Integer id; private String name; private String sex; @Value(value = "觀滄海") private String address; private Integer age; public Student() { } public Student(Integer id, String name, String sex, String address, Integer age) { this.id = id; this.name = name; this.sex = sex; this.address = address; this.age = age; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", sex=" + sex + ", address=" + address + ", age=" + age + "]"; } }
1. 註解方式
Spring會掃描到注有@Component的類,將他們新增到容器進行管理,使用者通過@Autowired
註解來將它注入業務場景,@Value註解會指定初始值
@Autowired Student student; /** * 註解方式 * * @return */ @RequestMapping("/viaano") public Object viaAnnotation() { return student; } 結果: { "id": 12, "name": null, "sex": null, "address": "觀滄海", "age": null }
2. 直接編碼方式
不管什麼方法最後都是通過編碼來實現的,不過我們也可以直接進行編碼
/**
* 直接編碼方式
* 把物件比作書,BeanFactory相當於圖書館,BeanDefinitionRegistry相當於書架
* @return
*/
@RequestMapping("/viacode")
public Object index() {
// 提供者
Supplier<Student> stu = () ->new Student(1,"loki","dd","saibotan",9);
// 定義Bean, beanDefinition例項儲存物件的所有必要資訊,每個受管理的物件在容器中都有一個beanDefinition與之對應
AbstractBeanDefinition beanDefinition = new RootBeanDefinition(Student.class, stu);
BeanDefinitionRegistry registry = new DefaultListableBeanFactory();
// 將bean定義註冊到容器中
registry.registerBeanDefinition("stu",beanDefinition);
// 指定依賴關係,通過構造方法注入
ConstructorArgumentValues argumentValues = new ConstructorArgumentValues();
argumentValues.addIndexedArgumentValue(0, beanDefinition);
beanDefinition.setConstructorArgumentValues(argumentValues);
// 可以使用了
BeanFactory beanFactory = (BeanFactory)registry;
Student student = (Student)beanFactory.getBean("stu");
return student;
}
結果:
{
"id": 1,
"name": "loki",
"sex": "dd",
"address": "saibotan",
"age": 9
}
3. 配置檔案方式
1. Properties檔案格式
# 檔名:spring-test.properties
stu.(class)=myspringboot.springboottest.entity.Student
stu.$0=2
stu.$1=傻強
stu.$2=s
stu.$3=address
stu.$4=33
# 可參考PropertiesBeanDefinitionReader的註釋文件
# 出現中文亂碼時,設定IDEA的FileEncoding
# 建構函式要傳入所有必要引數
/**
* 配置檔案方式1
* PropertiesBeanDefinitionReader是按Spring的檔案規則進行載入,
* 可以定義並實現自己的規則來載入和解析,不過沒有必要
*
* @return
*/
@RequestMapping("/viapro")
public Object viaProperties() {
// BeanDefinitionReader 實現類-->讀取對映配置檔案到BeanDefinition-->註冊到BeanDefinitionRegistry
BeanDefinitionRegistry definitionRegistry = new DefaultListableBeanFactory();
BeanDefinitionReader definitionReader = new PropertiesBeanDefinitionReader(definitionRegistry);
definitionReader.loadBeanDefinitions("classpath:spring-test.properties");
// 可以使用了
BeanFactory beanFactory = (BeanFactory)definitionRegistry;
Student student = (Student)beanFactory.getBean("stu");
return student;
}
結果:
{
"id": 2,
"name": "傻強",
"sex": "s",
"address": "address",
"age": 33
}
2. 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="stu" class="myspringboot.springboottest.entity.Student">
<constructor-arg name="id" value="1"></constructor-arg>
<constructor-arg name="name" value="張三"></constructor-arg>
<constructor-arg name="age" value="1"></constructor-arg>
<constructor-arg name="address" value="哈哈"></constructor-arg>
<constructor-arg name="sex" value="1"></constructor-arg>
</bean>
</beans>
/**
* 配置檔案方式2
* xml 支援最為完整,強大,同樣可以擴充套件
*
* @return
*/
@RequestMapping("/viaxml")
public Object viaXml() {
// BeanDefinitionReader實現類-->讀取對映配置檔案到BeanDefinition-->註冊到BeanDefinitionRegistry
BeanDefinitionRegistry definitionRegistry = new DefaultListableBeanFactory();
BeanDefinitionReader definitionReader = new XmlBeanDefinitionReader(definitionRegistry);
definitionReader.loadBeanDefinitions("classpath:spring-test.xml");
// 可以使用了
BeanFactory beanFactory = (BeanFactory)definitionRegistry;
Student student = (Student)beanFactory.getBean("stu");
return student;
}
結果:
{
"id": 1,
"name": "張三",
"sex": "1",
"address": "哈哈",
"age": 1
}
參考書籍: Spring揭祕 王福強 著