1. 程式人生 > >Spring中BeanFactory的物件註冊與依賴繫結方式

Spring中BeanFactory的物件註冊與依賴繫結方式

概念

  1. BeanFactory是spring的基礎型別IOC容器,提供完整的IOC服務支援
  2. 預設採用延遲初始化策略,當客戶端物件訪問受管物件時,才對其進行初始化和依賴注入

理解

  1. BeanFactory將每個物件看做一個bean,通過配置檔案,編碼,註解等方式獲取組裝這個bean的
    零件,最終對使用者提供一個獲取bean的介面
  2. 使用者不用關心bean如何組裝
  3. 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揭祕 王福強 著