Spring的主心骨
-
解析配置
-
定位与注册对象
-
注入对象
Bean&BeanDefinition
Bean是Spring中的一等公民
-
Bean的本质就是Java对象,只是这个Java对象的生命周期由Spring容器来管理和维护
-
不需要为了创建Bean而在原来的Java对象上添加任何额外的限制
-
对Java对象的控制方式体现在配置上或注解上
Spring会根据配置或注解生成用来描述Bean的BeanDefinition。
Java中Java对象是使用Class这个类来描述的,而在Spring则使用BeanDefinition来描述Bean
BeanDefinition常用的属性:
-
作用范围scope
Singleton,prototype, session,request等
-
懒加载 lazy-init
-
首选primary,设置为true的Bean会是优先的实现类
-
Factory-bean(工厂bean的名称),factory-method(工厂方法的名称)
容器初始化要做的事情:
- 将XML或注解读入到内存
- 内存中注解或配置文件会被当作Resource对象
- 解析成BeanDefinition实例
- 注入容器中
Spring中Bean的继承关系不是通过extends, implement 实现的,而是通过在BeanDefinition中设置parent属性来决定的。
RootBeanDefinition不能被设置为其他BeanDefinition的子属性,RootBeanDefinition可以承接两个BeanDefinition进行合并生成RootBeanDefinition合并除parent之外的所有属性。
Spring2.5之后使用GenericBeanDefinition来替代RootBeanDefinition和ChildBeanDefinition,但是由于之前一直使用RootBeanDefinition所以合并BeanDefinition还是使用的RootBeanDefinition。ChildBeanDefinition不能单独存在必须和RootBeanDefinition一起存在,ChildBeanDefinition已经被GenericBeanDefinition完全取代了。
GenericBeanDefinition通用的BeanDefinition
Spring容器都必须实现BeanFactory(顶级容器接口)接口
BeanFactory&FactoryBean
-
BeanFactory
是Spring IOC容器的根接口,定义Bean工厂的最基本特性,如获取Bean;用于管理Bean
-
FactoryBean
该接口的getObject方法用户可以使用一套复杂的逻辑生成Bean,FactoryBean本质也是一个Bean,但是这个Bean不是用来注入其他地方进行使用的(不像Service,Dao,Controller),而是用于生成普通Bean;对于实现了这个接口的Bean,Spring容器在初始化的时候会取出这些Bean,调用getObject()方法生成我们想要的Bean。
ListableBeanFactory
批量列出容器中实例的信息,如容器中Bean的名字,数量等
HierarchicalBeanFactory
使容器具有层次关系,查找当前容器的父级容器,判断Bean是否在当前容器中,只在当前容器中查找
AutowireCapableBeanFactory
使容器具有自动装配Bean的能力,根据类定义BeanDefinition去装配并执行前后处理器等
@Autowired注解实现自动装配最终就是调用这个类的如下方法实现的
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
ConfigurableBeanFactory
主要定义了设置父容器,容器类加载器,属性编辑器,容器通用的Bean后置处理器继承SingletonBeanRegistry 提供在运行期间向容器注册单例实例Bean的能力
ConfigurableListableBeanFactory
整合了BeanFactory体系的所有二级接口,忽略自动装配等10个方法
DefaultListableBeanFactory
真正第一个可以独立运行的IOC容器,继承AbstractAutowireCapableBeanFactory,实现集大成接口ConfigurableListableBeanFactory实现 BeanDefinitionRegistry 实现注册功能
一些术语讲解:
组件扫描:
自动发现应用容器中需要创建的Bean
自动装配:
Spring会自动满足Bean之间的依赖,
高级容器ApplicationContext
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
EnvironmentCapable:接口:用来获取Environment,获取容器的启动参数,如在启动main函数时设置的-Dparameter1=value1就可以通过返回的Environment实例获取到,也可以访问到Servlet的一些配置信息(如web.xml中配置的信息),如Environment实例的ConfigurableEnvironment
Environment extends PropertyResolver
public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver {
public interface ResourcePatternResolver extends ResourceLoader {
ApplicationEventPublisher使ApplicationContext具备事件发布的能力。
容器在启动的时候会给自身注册一些Listener,这些Listener会监听容器发布的事件,主要射击下面的监听类和事件类:
ApplicationEventMulticaster,ApplicationEvent
public interface EnvironmentCapable {
/**
* Return the {@link Environment} associated with this component.
*/
Environment getEnvironment();
}
ApplicationContext常用容器
FileSystemXmlApplicationContext:从文件系统加载配置
ClassPathXmlApplicationContext:从ClassPath加载配置
XmlWebXmlApplicationContext:用于Web应用容器加载配置
基于注解的常用ApplicationContext容器:
AnnotationConfigServletWebServiceApplicationContext在SpringBoot模块中
AnnotationConfigReactiveWebServiceApplicationContext—响应式容器 在SpringBoot模块中
AnnotationConfigApplicationContext
以上具体容器实现都适用于不同场景,实现也不一样,下面主要研究他们的共性。
refresh()(可以看作是IOC容器的启动方法)大致功能:
-
容器初始化,配置解析
-
BeanPostProcessor和BeanFactoryPostProcessor的注册与激活
-
国际化配置初始化
ApplicationContext中的方法都是读取方法,所有功能都是配置的,所以需要ConfigurableApplicationContext接口支持,
AbstractApplicationContext类是Spring高级容器中最重要的类,实现了ConfigurableApplicationContext,
这个抽象类实现了Application接口中简单不易动的部分,主要是容器工厂的处理,如:事件发送广播,监听器注册,refersh方法,getBean方法,没实现的也预留了方法由子类实现。
这个类refresh方法使用了模版方法模式:—子类为父类提供支持
模版方法模式
围绕抽象类,实现通用逻辑,定义模版结构,部分逻辑由子类实现。
优点:
- 复用代码,反向控制
模版方法中有三类方法:
-
具体公用方法基类实现,
-
抽象方法必须子类实现,
-
钩子方法预留的方法子类可以选择性的实现。
网友评论