spring02 容器实现
容器的实现
DefaultListableBeanFactory :BeanFactory 最重要的实现,控制反转,依赖注入都由它实现 ,ApplicationContext 组合了它
beanFactory 可以通过 registerBeanDefinition 注册一个 bean definition 对象
我们平时使用的配置类、xml、组件扫描等方式都是生成 bean definition 对象注册到 beanFactory 当中
bean definition 描述了这个 bean 的创建蓝图:scope 是什么、用构造还是工厂创建、初始化销毁方法是什么,等等
代码:
点击查看代码
//获得 BeanFactory 对象 控制反转,依赖注入功能
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//获得 BeanDefinition 对象,定义 Bean 的信息,BeanFactory 根据这些信息创建 Bean
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(Config.class) //设置哪个类的 Bean 信息
.setScope("singleton") //设置 Bean 的类型
.getBeanDefinition(); //得到 BeanDefinition
//将 BeanDefinition 注册到 BeanFactory 中
beanFactory.registerBeanDefinition("config",beanDefinition); //第一个参数 Bean 的名字
//遍历 BeanFactory 中的 BeanDefinition 可以看到其中的注解并没有被解析,说明 BeanFactory 没有这个功能,需要添加 BeanFactory 后处理器
for (String name : beanFactory.getBeanDefinitionNames()) {
System.out.println(name);
}
beanFactory 需要手动调用 beanFactory 后处理器对它做增强
例如通过解析 @Bean、@ComponentScan 等注解,来补充一些 bean definition
代码:
点击查看代码
//通过注解工具类给 BeanFactory 注册一些常见的后处理器(不全是 BeanFactory 后处理器)此时并没有与 BeanFactory 建立联系
/*
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
*/
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
for (String name : beanFactory.getBeanDefinitionNames()) {
System.out.println(name);
}
System.out.println("==================================");
//添加解析 @Configuration 与 @Bean 注解的 BeanFactoryPostProcess (都继承了 BeanFactoryPostProcess)
// org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class)
.values().forEach(b ->{
//执行后处理器(与 BeanFactory 建立联系)
b.postProcessBeanFactory(beanFactory);
});
for (String name : beanFactory.getBeanDefinitionNames()) {
System.out.println(name);
}
beanFactory 需要手动添加 bean 后处理器,以便对后续 bean 的创建过程提供增强
例如 @Autowired,@Resource 等注解的解析都是 bean 后处理器完成的
代码:
点击查看代码
//添加解析 @Autowired @Resource 等注解的 Bean 后处理器 (针对 bean 的生命周期的各个阶段提供扩展)
//org.springframework.context.annotation.internalAutowiredAnnotationProcessor
//org.springframework.context.annotation.internalCommonAnnotationProcessor
beanFactory.getBeansOfType(BeanPostProcessor.class)
.values().forEach(beanFactory::addBeanPostProcessor);
beanFactory.preInstantiateSingletons(); // 准备好所有单例 初始化
bean 后处理的添加顺序会对解析结果有影响,见视频中同时加 @Autowired,@Resource 的例子
@Autowired 根据类型匹配,同类型有多个根据首字母小写的变量名匹配
@Resource 根据类型匹配,也可通过指定 name 属性进行首字母小写的变量名匹配
两个同时存在,按 Bean 后处理器添加的顺序决定优先级,先添加的优先级高。
可以通过 BeanFactory 的 getDependencyComparator()方法来排序,在添加常用的后处理器时添加的排序方法,根据每个后处理器的 Order 值来排序,越小的优先级越高,排在前面
beanFactory 需要手动调用方法来初始化单例
beanFactory 需要额外设置才能解析 ${} 与 #{}
ApplicationContext相关的实现
ClassPathXmlApplicationContext:从类路径查找 xml 配置文件创建容器
代码
点击查看代码
ClassPathXmlApplicationContext classPathXmlApplicationContext =
new ClassPathXmlApplicationContext("s02.xml");
//也是调用 BeanFactory 的 getBeanDefinitionNames(),做了封装
for (String beanDefinitionName : classPathXmlApplicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
System.out.println(classPathXmlApplicationContext.getBean(Bean2.class).getBean3());
点击查看代码
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
System.out.println("=================");
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(new ClassPathResource("s02.xml"));
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
xml 文件
点击查看代码
<bean id="s01" class="cn.xyf.spring.s02.S02.Bean1"/>
<bean id="s02" class="cn.xyf.spring.s02.S02.Bean2">
<property name="bean3" ref="s03"/>
</bean>
<bean id="s03" class="cn.xyf.spring.s02.Bean3"/>
<!--添加一些常见的后处理器-->
<context:annotation-config/>
FileSystemXmlApplicationContext:从磁盘路径查找 xml 配置文件创建容器
代码
点击查看代码
FileSystemXmlApplicationContext fileSystemXmlApplicationContext
= new FileSystemXmlApplicationContext("D:\\code2\\spring\\src\\main\\resources\\s02.xml");
for (String beanDefinitionName : fileSystemXmlApplicationContext.getBeanFactory().getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
System.out.println(fileSystemXmlApplicationContext.getBean(Bean2.class).getBean3());
点击查看代码
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
System.out.println("=================");
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(new FileSystemResource("src/main/resources/s02.xml"));
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
XmlWebApplicationContext:传统 SSM 整合时,基于 xml 配置文件的容器
AnnotationConfigWebApplicationContext:传统 SSM 整合时,基于 java 配置类的容器
AnnotationConfigApplicationContext:SpringBoot 中非 Web 环境的容器(新)
代码
AnnotationConfigApplicationContext annotationConfigApplicationContext
= new AnnotationConfigApplicationContext(Config.class);
for (String beanDefinitionName : annotationConfigApplicationContext.getBeanFactory().getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
AnnotationConfigServletwebServerApplicationContext:SpringBoot 中servlet web 环境容器(新)
代码
点击查看代码
@Configuration
static class WebConfig {
// 内嵌 Web 容器
@Bean
public ServletWebServerFactory servletWebServerFactory() {
TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory();
tomcatServletWebServerFactory.setPort(8081);
return tomcatServletWebServerFactory;
}
// 访问的入口 将请求分发
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
// 注册 DispatcherServlet 到 Web 服务器
@Bean
public DispatcherServletRegistrationBean registration(DispatcherServlet dispatcherServlet) {
return new DispatcherServletRegistrationBean(dispatcherServlet, "/*");
}
@Bean("/hello")
public Controller controller1() {
return (request, response) -> {
response.getWriter().print("hello");
return null;
};
}
@Bean("/tests02")
public Controller controller() {
return (request, response) -> {
response.getWriter().print("come on !!!");
return null;
};
}
}
AnnotationConfigServletWebServerApplicationContext annotationConfigServletWebServerApplicationContext
= new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
for (String beanDefinitionName : annotationConfigServletWebServerApplicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
AnnotationConfigReactiveWebServerApplicationContext:SpringBoot 中 reactive web(Spring WebFlux,基于响应式的 Web 容器) 环境容器(新)

浙公网安备 33010602011771号