用过Spring的一定知道,Spring提供了IOC的功能,也就是反转控制,将对象之间的关系 转而使用配置来管理,从而提供了
依赖注入的功能。 Spring通过将对象包装在Bean中,来达到管理对象和进行其他额外操作的目的。
什么是Bean?
1.Bean的本质还是Java对象,只有这个对象的生命周期由容器来管理。
2.我们不需要为了创建一个Spring中的Bean而再原来的对象上做任何 额外的操作,因此说 Spring框架是低侵入或者是无侵入的框架。
3.既然没有改变原来的代码,我们平常是使用配置文件或者配置类来表示如何 管理这个类。
什么是BeanDefinition?
在JDK中,是采用Java.lang.class来描述一个对象。而在Spring中,就是通过BeanDefinition这个类来描述Bean的。Spring是通过读取配置文件或者配置类来生成BeanDefinition对象。
BeanDefinition由哪些属性?
相比你也很熟悉。
Scope(Singleton,prototype等等)
lazy-init(懒加载-用的时候才加载构造,不用的时候不加载);
singleton默认是非 懒加载,prototype 默认是懒加载。
懒加载 的好处是在使用的再加载节省资源,不利于提前发现错误。反之亦然。
primary(如果按照类型来装配,一个接口 有多个实现类,设置了这个属性的类会被优先使用)
factoryBean-工厂类的名称,同等效力的注解是@configuration(根据工厂类生成Bean实例)
<bean class="com.fuyouj.model.factory.StaticFactory" id="user2" factory-method="getUssr" scope="singleton"></bean>
public class StaticFactory {
public static User getUssr(){
return new User();
}
}
faxtory-Method-工厂方法的名称,同等效力的注解是@Bean(将某方法返回的类型交给容器管理)
<bean class="com.fuyouj.model.factory.UserFactory" id="userFactory"></bean>
<bean id="user3" factory-bean="userFactory" factory-method="getUser" scope="prototype"></bean>
public class UserFactory {
public User getUser(){
return new User();
}
}
不管我们是使用xml配置 文件还是配置类也好,Spring初始化容器都要经历 以下几个阶段。
1,读取配置文件或者其他配置类读取到内存总
2,在内存中,这些配置会被转换成一个个的Resource的实例
3,将Resource实例解析成BeanDefinition的实例。
4,根据BeanDefinition的指示注册到容器当中。(容器根据指示创建实例,比如是否是单例,懒加载,ID等等)
BeanDefinition接口
可以看到BeanDefinition继承了 AttributeAccessor, BeanMetadataElement两个接口。Spring中有大量的接口,每个类实现了某一个接口也就是承诺了拥有了某种能力。
AttributeAccessor接口定义用于附加和访问元数据的通用契约的接口(Interface defining a generic contract for attaching and accessing metadata),BeanDefinition继承这个接口主要是为了实现类提供获取本类的属性和一些设置操作。
而BeanDefinition的定义的方法太多,这里不贴图。总结下来就是一些定义Bean的属性和方法。(sccop,父类名字,延迟加载 ,是否单例,优先加载,工厂名字==)。
BeanMetadataElement接口只定义了了一个getSource方法 ,返回这个元数据元素的配置源。
BeanDefinition继承了这个接口,是用来返回BeanDefinition本身。
BeanDefinition仅仅是定义了接口,但是他继承了 AttributeAccessor, BeanMetadataElement两个接口,就能对BeanDefinition的谁能够进行操作了。就AttributeAccessorSupport是AttributeAccessor的实现抽象类,提供所有方法的简单实现。
AbstractBeanDefinition
AbstractBeanDefinition是所有BeanDefinition的实现类的基类。提供了一些操作BeanDefiniton的通用方法的实现,比如一个构造方法设置大量的属性,比如通过其他BeanDefiniton覆盖自己的属性。这里是值得 借鉴的,我就经常遇到要用其他类的属性覆盖自己类,而我就简单粗暴的新开一个方法,想了想还是我项目太小了的原因吧。如果涉及到有多个实现子类,且实现子类有共同需要实现的逻辑,可以考虑将通用的部分放在抽象类,而继承抽象类来复用能力。
AbstractBeanDefinition的三个实现类
RootBeanDefinition
RootBeanDefinition可以单独作为一个BeanDefinition和其他BeanDefinition的父类,但是不能作为其他BeanDefiniton的子类,这是怎么实现的呢?
@Override
public void setParentName(@Nullable String parentName) {
if (parentName != null) {
throw new IllegalArgumentException("Root bean cannot be changed into a child bean with parent reference");
}
}
可以看到,如果在 RootBeanDefinition里面设置Parent属性,就会抛出异常,我又感觉学到了。可以得出信息,Spring定义的Bean之间的继承关系,不是通过 关键字Implement或者 extends实现的,而时通过设置Parent属性来确定的。
GenericBeanDefinition
是新版本的实现 ,大部分的实现都用此类,而不是ROOT和Child.
主要区别在于多了一个parent属性。(ROOT是没有的)