撸一撸Spring Framework-IoC-BeanFactory
BeanFactory是Spring IoC中最核心的接口,它承担IoC最基本的职责,即创建并管理各种类的对象。BeanFactory接口只定义了最基础的IOC容器功能,它的扩展接口众多,继承体系设计优雅,堪称经典
撸一撸Spring Framework-IoC系列文章目录
BeanFactory是Spring IoC中最核心的接口,它承担IoC最基本的职责,即创建并管理各种类的对象。BeanFactory接口的关键方法getBean的实现中,会试图从缓存中查找并返回对应的bean,若不存在,则根据bean对应的bean definition来创建bean对象(包括实例化、属性赋值、依赖装配、初始化等工作,这部分工序加上bean的销毁,统称为为bean的生命周期),因此得名bean工厂
容器启动时,BeanFactory会从配置元信息中加载beanDefinition,之后的bean创建和管理工作都依赖于beanDefinition
配置元信息:包括xml文件、java configuration+注解两种形式,BeanFactory只支持前者,后者属于ApplicationContext的能力
beanDefinition:每个bean都来源于一个beanDefinition,它定义了bean的类名、构造器参数值、属性值、对其他bean的引用关系、scope等信息
BeanFactory接口只定义了最基础的IOC容器功能,它的扩展接口众多,继承体系设计优雅,堪称经典:
ListableBeanFactory:有时候一个class会对应多个bean,如果试图通过BeanFactory获取这多个bean,只能按beanName逐个查找
listable表示可列举的、可枚举的,它支持枚举同一个class对应的所有bean实例,比如方法Map<String, T> getBeansOfType(Class<T> type)返回1个包含了指定class所有bean的map(key为beanName,value为bean),我们可以用@Autowired List<T> xx、@Autowired Map<String,T> xx注入T类型对应的所有bean,正是得益于此
HierarchicalBeanFactory:hierarchical表示层次性的,它允许BeanFactory设置一个parent BeanFactory,在查找bean时,会首先委托给parent BeanFactory,如果没找到,再从当前BeanFactory查找,也就是父BeanFactory中的bean对子BeanFactory可见,反之不可见。我们熟知的父子容器,就是依赖于这一机制,它使得每个容器可以关注一个特定的层,实现关注点分离,比如在Spring MVC中,业务层和持久层位于父容器中,展现层位于子容器中,这样展现层可以引用业务层、持久层的bean,反之则不可以
AutowireCapableBeanFactory:autowire capable表示具有自动装配能力的,是针对外部对象来说的(不归spring管理的对象),比如你想自行控制一个类的创建工作,而非交给spring,但是你又想在类中使用spring中的bean,就可以这样操作:
package com.example.spring; import org.springframework.stereotype.Component; //spring管理的类 @Component public class SpringManagedService { } <!---------------------------分割线----------------------------!> package com.example.spring; import org.springframework.beans.factory.annotation.Autowired; //不归Spring管理的类 public class MyService { @Autowired private SpringManagedService springManagedService; @Override public String toString() { return "MyService{" + "springManagedService=" + springManagedService + '}'; } } <!---------------------------分割线----------------------------!> package com.example.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; @ComponentScan(basePackages ={"com.example.spring"} ) public class AutowireCapableDemo { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(); applicationContext.register(AutowireCapableDemo.class); applicationContext.refresh(); //自行实例化 MyService myService=new MyService(); applicationContext.getAutowireCapableBeanFactory().autowireBean(myService); System.out.println(myService.toString()); applicationContext.close(); } }
ConfigurableBeanFactory:configurable表示可配置的,它其中包含了众多的setXX、addXX、registerXX方法使我们可以定制BeanFactory,比如addBeanPostProcessor、registerScope(自定义singleton、prototype之外的scope,比如request、session、application等在web应用中使用的scope)、setApplicationStartup(Spring在容器启动过程中的各个关键步骤,会调用ApplicationStartup#start方法启动、终止一个个的StartupStep(表示一个步骤的开始与结束),可以用于记录一些指标信息,比如记录各阶段耗费的时间)
ConfigurableBeanFactory还继承于SingletonBeanRegistry,SingletonBeanRegistry的核心方法registerSingleton(String beanName, Object singletonObject)允许客户端向BeanFactory中注册一个外部对象(不归spring管理的对象),使之成为spring内部的单例bean,要注意的是该对象应该是已经完整初始化过的,spring不会再对其执行任何与生命周期回调的相关逻辑
DefaultListableBeanFactory:作为上述所有BeanFactory接口的完整实现,它无疑是非常重要的,在众多ApplicationContext实现中,都持有一个DefaultListableBeanFactory引用,所有bean管理的操作都会委托给DefaultListableBeanFactory
同时它还实现了BeanDefinitionRegistry接口,该接口作为beanDefinition注册中心的抽象,提供了beanDefinition的注册、删除、查询、计数等方法
在Spring容器的启动阶段,从配置元信息中加载到的beanDefinition,会通过registerBeanDefinition方法保存下来(内存中),后续操作直接从中读取。spring还允许开发者在运行时注册新的beanDefinition、或者修改已有的beanDefinition信息,这无疑提高了bean定义机制的灵活性
public class BeanFactoryDemo { public static void main(String[] args) { //创建一个空的bean工厂 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //向工厂里添点原材料(beanDefinition),BeanFactory支持两种添加beanDefinition的方式 //1、从xml中加载 XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); //通过ResourceLoader加载resources下的xml资源 Resource resource = new DefaultResourceLoader().getResource("classpath:bean.xml"); //从xml资源中读取beanDefinition reader.loadBeanDefinitions(resource); //2、调用注册api BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(User.class).getBeanDefinition(); beanDefinition.getPropertyValues().add("id", "002"); beanDefinition.getPropertyValues().add("name", "li si"); beanFactory.registerBeanDefinition("user2", beanDefinition); //获取所有User类型的bean Map<String, User> userMap = beanFactory.getBeansOfType(User.class); //输出-->{user1=User{id='001', name='zhang san'}, user2=User{id='002', name='li si'}} System.out.println(userMap); } } public class User{ private String id; private String name; public User(String id, String name) { this.id = id; this.name = name; } public User() { } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; } }
更多推荐
所有评论(0)