• 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揭秘 王福强 著

  • 相关阅读:
    html基础起航
    必杀技———SQL基础整理系列(一)
    JavaScript代码段整理笔记系列(一)
    与JSP的初次邂逅……
    产品第二篇
    产品第一篇
    进程在后台可靠运行的几种方法
    Vue.js模板语法
    更靠谱的横竖屏检测方法
    浮动【电梯】或【回到顶部】小插件:iElevator.js
  • 原文地址:https://www.cnblogs.com/Lothlorien/p/9964747.html
Copyright © 2020-2023  润新知