BeanFactory

Spring提供的IoC容器包括BeanFactory,ApplicationContent。IoC容器包含了IoC Service Provider的功能
BeanFactory,基础类型IoC容器,提供完整的IoC服务支持,默认延迟初始化策略,速度快,提供资源有限
ApplicationContent在BeanFactory的基础上构建,提供了比如事件发布等其他特性,容器启动后直接初始化,速度稍慢,提供资源较多
Application继承了BeanFactory

BeanFactory的对象注册与依赖绑定方式
1.直接编码方式
DefaultListableBeanFactory实现了BeanFactory接口和BeanDefinitionRegistry接口,BeanDefinitionRegistry是在BeanFactory的实现中负责Bean注册管理。BeanFactory仅仅定义如何访问容器内管理的Bean方法,由BeanFactory的具体实现类负责具体Bean的注册和管理。
2.外部配置文件方式
properties、xml文件
读取外部文件的配置,IoC容器需要对应文件格式的BeanFefinitionReader的实现类,由其读取并映射到BeanDefinition,由BeanDefinition注册到BeanDefinitionRegistry,BeanDefinitionRegistry完成对Bean的注册和加载
3.注解方式
@Autowired、@Componment进行标记
@Autowired告诉了IoC当前对象要注入哪些依赖对象,@Componment需要配合classpath-scanning使用
```
<context:component-scan base-package="cn.spring.project.base.package"/>
```
context:component-scan会在指定目录下搜索标注了@Component的类,并添加到IoC容器,根据@Autowired注入依赖对象

XML注入
1.<beans> <bean>的结构
多个<bean>组成一个<beans>
<beans>拥有属性对其下的<bean>做统一管理
<bean>对应个体的业务对象
id:唯一标志,可以没有
name:alias,别名,可以适应特殊字符,可以多个
class:类型,一般要有

2.构造方法注入
<constructor-arg>
```
<constructor-arg ref="class.name"> 或
<constructor-arg>
<ref bean="class.name"/>
</constructor-arg>
```
<constructor-arg> type或index 标志注入参数的类型和次序
```
class A
{
String aStr;
int aInt;

public A(String aStr){

}

public A(int aInt){

}
}

<bean id="a" class="...A">
<constructor-arg type="int">
<value>111</value>
</constructor-arg>
</bean>
```
3.setter方法注入
<property>
<name> 注入对象对应实例,入参变量名称
与<constructor-arg>并不矛盾

<list> <map> <set> 和Java容器对应的标签

<depends-on> 保证容器在实例化A之前先实例化B

<autowire> 将相互依赖的bean直接自动绑定
参数:no
byName
byType
constructor
autodetect = byType + constructor
手动绑定会覆盖自动绑定
自动绑定会节省手工输入量,会自动适应一些新的修改。但是基于类型、命名的自动绑定,个人认为并不稳定、健壮

<dependency-check> 对依赖对象进行检查

<lazy-init> 延迟初始化
当被标记延迟初始化的对象被非延迟初始化的对象依赖时,标记失效

<parent> 继承 参数值为bean id
使用模板化配置形式配置
```
<bean id="newsProviderTemplate" abstract="true">
<property name="newParsister"/>
<ref bean="djNewsPersister"/>
</property>
</bean>

<bean id="superNewsProvider" parent="newsProviderTemplate" class="..FXNewsProvider">
<property name="newsListener">
<ref bean="djNewsListener"/>
</property>
</bean>
```

<scope> 对象的生命周期管理 声明容器中的对象所应该处的限定场景或者说该对象的存活时间
singleton 在IoC容器的生命周期内仅存在一个该对象的实例
prototype 容器每次返回给请求方一个新的对象实例
以下时支持web应用的ApplicationContext可以使用scope value
request
session
global session
自定义scope类型

<factory-method>
```
public class StaticInterfaceFactory
{
publi static Interface getInstance()
{
return new InterfaceImpl();
}
}

<bean id="a" class="..A">
<property name="Interface">
<ref bean="i"/>
</property>
</bean>

<bean id="i" class="..StaticInterfaceFactory" factory-method="getInstance"/>
```
对于静态工厂方法,factory-method 指定方法应是静态的,通过静态避免了在bean配置中实例化工厂类
下面是非静态工厂方法(实例工厂方法)

```
public class InterfaceFactory
{
publi Interface getInstance()
{
return new InterfaceImpl();
}
}

<bean id="a" class="..A">
<property name="Interface">
<ref bean="i"/>
</property>
</bean>

<bean id="i" class="..InterfaceFactory"/>

<bean id="i" Factory-bean="..i" factory-method="getInstance"/>
```

FactoryBean
可以拓展容器对象实例化逻辑的接口,Factory修饰Bean
当某些对象的实例化过程复杂繁琐,需要借助模式处理时,XML配置复杂 或 不能直接注册时,可以实现FactoryBean接口。
```
public class NextDayDateDisplayer
{
private DateTime dateOfNextDay;
}

public class NextDayDateFactoryBean implements FactoryBean
{

public Object getObject() throws Exception
{
return new DateTime().plusDays(1);
}

public Class getObjectType()
{
return DateTime.class;
}

public boolean isSingleton()
{
return false;
}
}

<bean id="nextDayDataDisplayer" class="...NextDayDateDisplayer">
<property name="dataOfNextDay">
<ref bean="nextDayDate"/>
</property>
</bean>

<bean id="nextDayDate" class="...NextDayDateFactoryBean" />
```
FactoryBean生产的对象类型是符合实现接口的具体FactoryBean所定义的类型,这使得业务对象的接入是非侵入式的,只需要配置好FactoryBean

“容器背后的秘密”
IoC容器会加载Configuration MetaData(配置数据,如XML配置信息),根据以上信息绑定对象。组装成可提供可使用对象、绑定依赖对象的容器。可分为两个阶段,容器启动阶段、Bean实例化阶段
1.容器启动阶段
加载配置、分析配置信息、装备到BeanDefinition、其他后处理
2.Bean实例化阶段
实例化对象、装配依赖、生命周期回调、对象其他处理、注册回调接口

在实例化对象之前的“钩子”,即容器启动阶段
BeanFactoryPostProcessor接口

1.PropertyPlaceHolderConfigurer
对XML文件的配置信息使用占位符,用properties文件进行加载
```
<property name="url">
<value>${jdbc.url}</value>
</property>
```
当该类被调用时,会替换占位符;这时还没有实例化对象,因此实例化对象的对应参数值是替换后的

2.PropertyOverrideConfigurer
对Bean定义的property信息进行替换

3.CustomEditorConfigurer
由XML文件的字符串类型映射到对象的各种类型的转化

“了解bean的一生”
Bean的实例化过程:实例化bean对象,设置对象属性,检查Aware相关接口并设置相关依赖,BeanPostProcessor前置处理,检查是否是InitializingBean以决定是否调用afterPropertiesSet方法,检查是否配置有自定义的init-method,BeanPostProcesser后置处理,注册逼向的Destruction相关回调接口,使用中,是否实现DisposableBean接口,是否配置有自定义的destroy方法
1.Bean的实例化与BeanWrapper
容器根据相应bean定义的BeanDefition取得实例化信息并完成实例化,得到以BeanWarpper构成的对象实例,BeanWrapper是基于反射API的封装
2.Aware接口
BeanNameAware、BewanClassLoaderAware、BeanFactoryAware。实现了这些接口的对象实例会注入相关信息
3.BeanPostProcessor
和BeanFactoryPostProcessor比较,在实例化阶段对实例化对象进行的“钩子”;BeanFactoryPostPrecessor处理的是符合条件的BeanDefinition,BeanPostProcessor处理的是符合条件的对象实例
posted @ 2019-06-26 21:07  Elinlinlin  阅读(294)  评论(0编辑  收藏  举报