此文章参考 Spring文档翻译
IoC容器为了避免在实例化Bean是出现错误,一般在实例Container是就会提前装配Scope为singleton(默认)的bean。如果此Bean有其他依赖的Bean ,则其他依赖Bean也会被装配。
Inner beans (内部Bean) :
<bean id="outer" class="...">
<!-- instead of using a reference to a target bean, simply define the target bean inline -->
<property name="target">
<bean class="com.example.Person"> <!-- this is the inner bean -->
<property name="name" value="Fiona Apple"/>
<property name="age" value="25"/>
</bean>
</property>
</bean>
内部bean定义不需要定义的id或名称; 如果指定,容器不使用这样的值作为标识符。 容器在创建时也忽略scope
标志:内部bean 总是匿名的,它们总是用外部bean创建。 将内部bean注入到协作bean中而不是注入到封闭bean中或者独立访问它们是不可能的。
作为一种角落情况,可以从自定义范围接收销毁回调,例如。 对于包含在单例bean内的请求范围内部bean:内部bean实例的创建将绑定到其包含的bean,但销毁回调允许它参与请求范围的生命周期。 这不是一个常见的情况; 内部bean通常简单地共享它们被包含bean的范围。
Collections 集合
Java
Collection
类型
List
,
Set
,
Map
和
Properties
的属性和参数我们一般直接在<list/>
,<set/>
,<map/>
和<props/>
元素中就可以设置,如下。
<bean id="moreComplexObject" class="example.ComplexObject">
<!-- results in a setAdminEmails(java.util.Properties) call -->
<property name="adminEmails">
<props>
<prop key="administrator">administrator@example.org</prop>
<prop key="support">support@example.org</prop>
<prop key="development">development@example.org</prop>
</props>
</property>
<!-- results in a setSomeList(java.util.List) call -->
<property name="someList">
<list>
<value>a list element followed by a reference</value> <!-- 这里是一些List元素,也可以用ref>
<ref bean="myDataSource" />
</list>
</property>
<!-- results in a setSomeMap(java.util.Map) call -->
<property name="someMap">
<map>
<entry key="an entry" value="just some string"/>
<entry key ="a ref" value-ref="myDataSource"/>
</map>
</property>
<!-- results in a setSomeSet(java.util.Set) call -->
<property name="someSet">
<set>
<value>just some string</value>
<ref bean="myDataSource" />
</set>
</property>
</bean>
容器还支持集合的合并。 一个应用程序开发人员可以定义一个父类型 <list/>
, <set/>
, <map/>
或者<props/>
, <list/>``<set/>
,<map/>
或<props/>
元素继承并覆盖父集合中的值。 也就是说,子集合的值是合并父和子集合的元素的结果,子集合元素覆盖父集合中指定的值。
<beans>
<bean id="parent" abstract="true" class="example.ComplexObject">
<property name="adminEmails">
<props>
<prop key="administrator">administrator@example.com</prop>
<prop key="support">support@example.com</prop>
</props>
</property>
</bean>
<bean id="child" parent="parent">
<property name="adminEmails">
<!-- the merge is specified on the child collection definition -->
<props merge="true">
<prop key="sales">sales@example.com</prop>
<prop key="support">support@example.co.uk</prop>
</props>
</property>
</bean>
<beans>
在child
bean定义的adminEmails
属性的<props />
元素上使用merge = true
属性。 当child
bean被容器解析和实例化时,生成的实例会有一个adminEmails``Properties
集合,其中包含子集adminEmails
collection与父集合'adminEmails`集合的合并结果。
administrator=administrator@example.com
sales=sales@example.com
support=support@example.co.uk
不能合并不同的集合类型(例如一个Map
和一个List
),如果这样做,一个Exception
被抛出。 merge
属性必须在下层,继承,子定义上指定; 在父集合定义上指定merge
属性是多余的,并且不会导致所需的合并。
Null and empty string values (null和空字符串)
Spring将空参数的属性等作为空的字符串处理。 以下基于XML的配置元数据片段将email属性设置为空的“String”值(“”)。
<bean class="ExampleBean">
<property name="email" value=""/>
</bean>
以上配置等同于以下Java代码:
exampleBean.setEmail("")
<null/>
元素用来处理null值。 例如:
<bean class="ExampleBean">
<property name="email">
<null/>
</property>
</bean>
以上配置等同于以下Java代码:
exampleBean.setEmail(null)
XML shortcut with the p-namespace (使用P命名空间简化操作)
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="classic" class="com.example.ExampleBean"> <property name="email" value="foo@bar.com"/> </bean> <bean name="p-namespace" class="com.example.ExampleBean" p:email="foo@bar.com"/> </beans>个人不喜欢这样,还是用 property 节点检查修改起来更加的方便
Compound property names (组合属性名称)
<bean id="foo" class="foo.Bar">
<property name="fred.bob.sammy" value="123" />
</bean>
关于depends-on :
如果bean是另一个的依赖,通常意味着一个bean被设置为另一个的属性。 通常你用<ref />
element 在XML中配置依赖。 然而,有时bean之间的依赖不直接; 例如,类的静态块初始化,又比如数据库驱动程序注册。 depends-on
属性可以在使用此元素的bean初始化之前明确强制一个或多个bean被初始化。 以下示例使用 depends-on
属性来表示对单个bean的依赖关系:
<bean id="beanOne" class="ExampleBean" depends-on="manager"/>
<bean id="manager" class="ManagerBean" />
多个依赖可以用逗号,空格,分号隔开
<bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
<property name="manager" ref="manager" />
</bean>
<bean id="manager" class="ManagerBean" />
<bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" />
Lazy-initialized beans(延迟初始化bean)
默认情况下,ApplicationContext
实现急切地创建和配置所有singleton bean作为初始化过程的一部分。 通常,这种预实例化是期望的,因为配置或周围环境中的错误被立即发现,而不是数小时或甚至数天之后。 当这种行为不是所期望的,你可以通过将bean定义标记为延迟初始化来阻止单例bean的预实例化。 一个延迟初始化的bean告诉IoC容器在第一次请求时而不是在启动时创建一个bean实例。
在XML中,此行为由<bean/>
元素上的lazy-init
属性控制; 例如:
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>
<bean name="not.lazy" class="com.foo.AnotherBean"/>
但是,当一个延迟初始化的bean是单例bean的依赖,而这个单例bean又
不是
lazy初始化时,ApplicationContext在启动时创建延迟初始化的bean,因为它必须满足singleton的依赖。因此延迟加载的bean会被注入单例bean。