直接量要通过<value/>元素来设置。<value/>元素通过字符串来指定属性或构造器参数的值。PropertyEditor将用于把字符串从java.lang.String类型转化为实际的属性或参数类型。
可以用于直接量和bean。不会验证bean的存在性。
idref元素用来将容器内其它bean的id传给<constructor-arg/> 或 <property/>元素,同时提供错误验证功能。idref标记允许容器在部署时验证所被引用的bean是否存在。
<bean id="theTargetBean" class="..."/> <bean id="theClientBean" class="..."> <property name="targetName"> <idref bean="theTargetBean" /> </property> </bean>
此外,如果被引用的bean在同一XML文件内,且bean名字就是bean id,那么可以使用local属性,此属性允许XML解析器在解析XML文件时来对引用的bean进行验证。
<property name="targetName"> <idref local="theTargetBean"/> </property>
在<constructor-arg/>或<property/>元素内部还可以使用ref元素。该元素用来将bean中指定属性的值设置为对容器中的另外一个bean的引用。该引用bean将被作为依赖注入,而且在注入之前会被初始化。
通过id/name指向另外一个对象有三种不同的形式。
第一种形式:
<ref bean="someBean"/>
可以引用同一容器或父容器内的任何bean(无论是否在同一XML文件中)。XML ‘bean’元素的值既可以是指定bean的id值也可以是其name值。
第二种形式:
<ref local="someBean"/>
可以利用XML解析器来验证所引用的bean是否存在同一文件中。local属性值必须是目标bean的id属性值。如果在同一配置文件中没有找到引用的bean,XML解析器将抛出一个例外。
第三种方式:
<ref parent="accountService"/>
parent属性来引用当前容器的父容器中的bean。可以是目标bean的id值,也可以是name属性值。
所谓的内部bean(inner bean)是指在一个bean的<property/>或 <constructor-arg/>元素中使用<bean/>元素定义的bean。内部bean定义不需要有id或name属性,即使指定id 或 name属性值也将会被容器忽略。
<bean id="outer" class="..."> <property name="target"> <bean class="com.mycompany.Person"> <!-- this is the inner bean --> <property name="name" value="Fiona Apple"/> <property name="age" value="25"/> </bean> </property> </bean>
注意:map的key或value值,或set的value值不能是以下元素:
bean | ref | idref | list | set | map | props | value | null
<bean id="moreComplexObject" class="example.ComplexObject"> <!--java.util.Properties --> <property name="adminEmails"> <props> <prop key="administrator">administrator@somecompany.org</prop> <prop key="support">support@somecompany.org</prop> <prop key="development">development@somecompany.org</prop> </props> </property> <!--java.util.List --> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource" /> </list> </property> <!--java.util.Map --> <property name="someMap"> <map> <entry> <key> <value>yup an entry</value> </key> <value>just some string</value> </entry> <entry> <key> <value>yup a ref</value> </key> <ref bean="myDataSource" /> </entry> </map> </property> <!--java.util.Set --> <property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource" /> </set> </property> </bean>
不同的集合类型是不能合并,merge属性必须在继承的子bean中定义。
<bean id="parent" abstract="true" class="example.ComplexObject"> <property name="adminEmails"> <props> <prop key="administrator">administrator@somecompany.com</prop> <prop key="support">support@somecompany.com</prop> </props> </property> </bean> <bean id="child" parent="parent"> <property name="adminEmails"> <props merge="true"> <prop key="sales">sales@somecompany.com</prop> <prop key="support">support@somecompany.co.uk</prop> </props> </property> </bean>
<bean class="ExampleBean"> <property name="email"><null/></property> </bean>
<property/>、<constructor-arg/>及<entry/>元素都支持value属性(attribute),它可以用来替代内嵌的<value/>元素。
<property name="myProperty" value="hello"/> <constructor-arg value="hello"/> <entry key="myKey" value="hello"/>
<property/>和<constructor-arg/>支持类似的简写属性ref,它可能用来替代整个内嵌的<ref/>元素。
<property name="myProperty" ref="myBean"/> <constructor-arg ref="myBean"/>
map中entry元素的简写形式为key/key-ref 和 value /value-ref属性
<entry key-ref="myKeyBean" value-ref="myValueBean"/>
<bean id="foo" class="foo.Bar"> <property name="fred.bob.sammy" value="123" /> </bean>
foo bean有个fred属性,此属性有个 bob属性,而bob属性又有个sammy属性,最后把sammy属性设置为123。
有时候bean之间的依赖关系并不是那么的直接。例如,当类中的静态块的初始化被时,如数据库驱动的注册。depends-on属性可以用于当前bean初始化之前显式地强制一个或多个bean被初始化。
<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" />
在bean层次中设置:
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"> <!-- various properties here... --> </bean>
在容器层次设置:
<beans default-lazy-init="true"> <!-- no beans will be eagerly pre-instantiated... --> </beans>
如果一个bean被设置为延迟初始化,而另一个非延迟初始化的singleton bean依赖于它,那么当ApplicationContext提前实例化singleton bean时,它必须也确保所有上述singleton 依赖bean也被预先初始化,当然也包括设置为延迟实例化的bean。因此,如果Ioc容器在启动的时候创建了那些设置为延迟实例化的bean的实例,你也不要觉得奇怪,因为那些延迟初始化的bean可能在配置的某个地方被注入到了一个非延迟初始化singleton bean里面。