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