容器级生命周期接口方法:在上图中带“★” 的步骤是由 InstantiationAwareBean PostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“ 后处理器” 。 后处理器接口一般不由 Bean 本身实现,它们独立于 Bean,实现类以容器附加装置的形式注册到Spring容器中并通过接口反射为Spring容器预先识别。当Spring 容器创建任何 Bean 的时候,这些后处理器都会发生作用,所以这些后处理器的影响是全局性的。当然,用户可以通过合理地编写后处理器,让其仅对感兴趣Bean 进行加工处理
ApplicationContext和BeanFactory不同之处在于:
ApplicationContext会利用Java反射机制自动识别出配置文件中定义的BeanPostProcessor、 InstantiationAwareBeanPostProcesso 和BeanFactoryPostProcessor后置器,并自动将它们注册到应用上下文中。而BeanFactory需要在代码中通过手工调用addBeanPostProcessor()方法进行注册
ApplicationContext在初始化应用上下文的时候就实例化所有单实例的Bean。而BeanFactory在初始化容器的时候并未实例化Bean,直到第一次访问某个Bean时才实例化目标Bean。
有了上面的知识点了,我们再来详细地看看Bean的初始化过程:
简要总结:
BeanDefinitionReader读取Resource所指向的配置文件资源,然后解析配置文件。配置文件中每一个<bean>解析成一个BeanDefinition对象,并保存到BeanDefinitionRegistry中;
容器扫描BeanDefinitionRegistry中的BeanDefinition;调用InstantiationStrategy进行Bean实例化的工作;使用BeanWrapper完成Bean属性的设置工作;
单例Bean缓存池:Spring 在DefaultSingletonBeanRegistry类中提供了一个用于缓存单实例 Bean 的缓存器,它是一个用HashMap实现的缓存器,单实例的Bean以beanName为键保存在这个HashMap中。
1.3IOC容器装配Bean 1.3.1装配Bean方式Spring4.x开始IOC容器装配Bean有4种方式:
XML配置
注解
JavaConfig
基于Groovy DSL配置(这种很少见)
总的来说:我们以XML配置+注解来装配Bean得多,其中注解这种方式占大部分!
1.3.2依赖注入方式依赖注入的方式有3种方式:
属性注入-->通过setter()方法注入
构造函数注入
工厂方法注入
总的来说使用属性注入是比较灵活和方便的,这是大多数人的选择!
1.3.3对象之间关系<bean>对象之间有三种关系:
依赖-->挺少用的(使用depends-on就是依赖关系了-->前置依赖【依赖的Bean需要初始化之后,当前Bean才会初始化】)
继承-->可能会用到(指定abstract和parent来实现继承关系)
引用-->最常见(使用ref就是引用关系了)
1.3.4Bean的作用域Bean的作用域:
单例Singleton
多例prototype
与Web应用环境相关的Bean作用域
reqeust
session
使用到了Web应用环境相关的Bean作用域的话,是需要我们手动配置代理的~
原因也很简单:因为我们默认的Bean是单例的,为了适配Web应用环境相关的Bean作用域--->每个request都需要一个对象,此时我们返回一个代理对象出去就可以完成我们的需求了!
将Bean配置单例的时候还有一个问题:
如果我们的Bean配置的是单例,而Bean对象里边的成员对象我们希望是多例的话。那怎么办呢??
默认的情况下我们的Bean单例,返回的成员对象也默认是单例的(因为对象就只有那么一个)!
此时我们需要用到了lookup方法注入,使用也很简单,看看例子就明白了:
1.3.6处理自动装配的歧义性昨天在刷书的时候刚好看到了有人在知乎邀请我回答这个问题:
结合两本书的知识点,可以归纳成两种解决方案:
使用@Primary注解设置为首选的注入Bean
使用@Qualifier注解设置特定名称的Bean来限定注入!
也可以使用自定义的注解来标识
1.3.7引用属性文件以及Bean属性之前在写配置文件的时候都是直接将我们的数据库配置信息在里面写死的了:
其实我们有更优雅的做法:将这些配置信息写到配置文件上(因为这些配置信息很可能是会变的,而且有可能被多个配置文件引用).
如此一来,我们改的时候就十分方便了。
引用配置文件的数据使用的是${}
除了引用配置文件上的数据,我们还可以引用Bean的属性:
引用Bean的属性使用的是#{}