1.bean 就是由spring容器(org.springframework.beans.factory.BeanFactory)初始化,装配,及管理的对象,BeanFactory是IoC容器的核心接口.
2.ApplicationContext 接口是 BeanFactory接口的扩展,继承BeanFactory.
3.XML配置元数据结构:将配置文件拆分成多个部分是非常有用的,为了加载多个XML文件生成一个ApplicationContext实例,可以将文件路径作为字符数组传给ApplicationContext构造器(如ClassPathXmlApplicationContext).另一种方法是使用<import/>元素,如<import resource="services.xml">.我们一般更倾向于第一种做法,因为这样各个配置并不会察觉到它们与其他配置文件的组合.
4.实例化Bean:
^1.(By构造器)当我们采用XML描述配置元数据时候将通过<bean/>元素的class属性来制定的实例化对象的类型.容器将直接通过反射调用指定累的构造器来创建bean(类似 new),
^2.(By静态工厂方法)除了指定class属性外,还需要factory-method属性来指定创建bean实例的工厂方法,spring将调用此方法返回对象,注意我们并不需要指定此方法返回对象类型!
<bean id="exampleBean" class="org.ExampleBean" factory-method="getInstance"/>
^3.(By实例工厂方法)与2类似,容器先实例化beanA,用beanA调用它们工厂方法去生产beanB.为使用此机制,beanB的class属性必须为空,beanB必须新增一个属性factory-method用来指定包含生产beanB工厂方法的beanA的名称.
<bean id="beanA" class="org.beanBFactory"/>
<bean id="beanB" factory-bean="beanA" factory-method="createBInstance"/>
-----------------------------------------------------------------------------------------------------------------------------
1.依赖注入(DI)背后的基本原理是对象间的依赖关系,只会通过一下几种方式来实现:
^构造器参数
^工厂方法的参数
^给构造方法或工厂方法创建的对象设置属性.
因此,容器的工作就是创建bean时注入那些依赖关系.相对于bean自己控制其实例化,直接在构造中指定依赖关系自主控制依赖关系注入方法说,控制从根本上发生了倒转,这也正是(IoC)控制反转的由来.
BeanFactory对于它所管理的bean提供两种注入依赖方式,需要注入的依赖将保存在org.springframework.beans.factory.config.BeanDefinition中,它能一句指定的PropertyEditor实现完成数据类型的装换(如dataSource中的<property />元素的 'value'属性).我们采用XML方式来定义,在内部这些定义将被装换成相应类实例,并最终得到一个Spring IoC容器实例.
^1.构造器注入:
^^类型明确,按顺序自己动匹配
构造方法如 :public Foo(Bar,Baz baz){
//...
}
假如 Bar Baz 不存在关系:
<bean name="foo" class="x.y.Foo">
<constructor-arg> <bean class="x.y.Bar"></constructor-arg>
<constructor-arg> <bean class="x.y.Baz"></constructor-arg>
</bean>
^^但是当使用原始数据类型时,我们需要使用'type'属性显示指定那些构造参数类型如:
<bean id="examBean" class="org.ExamBean">
<constructor-arg type="int" value="111">
<constructor-arg type="java.lang.String" value="lzpeng">
</bean>
^^我们也可以通过显示指定构造参数的索引,如:
<bean id="examBean" class="org.ExamBean">
<constructor-arg index="0" value="111">
<constructor-arg index="1" value="lzpeng">
</bean>
^2.setter注入:
//...........
2.处理bean依赖关系步骤:
^1.根据定义bean的配置(文件)创建并初始化BeanFactory实例.(容器这时会验证每个bean配置,如引用属性是否有效,循环依赖等.)
^2.每个bean的依赖将以属性,构造器参数,静态工厂方法参数的形式出现,当这些bean被实际创建时,这些依赖将会提供给bean.
^3.每个属性或构造器参数可以是实际的值,也可以是对该容器另一个bean的引用.
^4.每个指定的属性或构造器参数值必须能够被转换成特定的格式或构造参数所需的类型.
3.一种配置,多种方式(For Best Practice):
^1.<bean id="dataSource" class="x.y.DataSource">
<property name="driverClass">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>com.mysql.jdbc.Driver</value>
</property>
</bean>
^2.<bean id="dataSource" class="x.y.DataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="url" value="com.mysql.jdbc.Driver"/>
</bean>
4.????
^1.idref元素允许在容器部署时验证所引用的bean是否存在,所以我们用<idref />元素,而非用<property />元素的'value'属性.
^2.<ref /> 的属性 - 'bean' OR 'local'
^^1.bean属性我们可以指定任何存在的bean的name OR id.
^^2.local属性我们只能指定同一文件中的 bean 的 id 属性值.
^^另:我们可以通过ref元素的parent属性指定父容器中的bean
^3.通过<list/>,<set/>,<map/>,<props>元素分别对应java中的List,Set,Map,Properties对应.
5.延迟初始化bean:
<bean id="lazy" class="x.y.BeanA" lazy-init="true"/> //缺点:如果有错误只能当程序用到它时被发现
<bean id="not.lazy" class="x.y.BeanB" />
lazy Bean不会在ApplicationContext启动时候实例化,但如果beanB依赖beanA,那么容器启动时beanA照样被实例化.
other --- <beans default-lazy-init="true">
6.自动装配(autowire)协作者(引用其它bean)
//..............
----------------------------------------------------------------------------------------------------
Bean的作用域:
1.singleton(spring默认作用域) : 每个IoC容器中一个bean定义对应一个对象实例(该实例在IoC容器中共享),该实例会被存储到单例缓存(singleton cache)中.
2.prototype(资源浪费者):一个bean定义对应多个对象实例.每次对该bean的请求(XML中对它每个引用,每次getBean())时都会创建一个新的bean实例.
^<bean id="StuService" class="x.y.StuService" scope="prototype">
^<bean id="StuService" class="x.y.StuService" singleton="false">
对于prototype作用域bean,我们需要自己释放它持有的资源 (可通过 bean后置处理器)
3.request
4.session
5.global
----------------------------------------------------------------------------------------------------
定制自己的Bean
^1.初始化回调 : 我们可以采用 <bean />元素的 'init-method'属性指定bean初始化方法.
^2.析构回调 : 我们可以采用 <bean />元素的 'destroy-method'属性指定bean析构方法.
<beans default-init-method="init">
另:在非web应用中关闭容器 - 调用AbstractApplicationContext实现的registerShutdownHook().