企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
你可以以定义属性和构造参数来引用其他bean,或者定义为内部值.xml的元素`<property/> `和` <constructor-arg/>`用来支持配置. [TOC] ## Straight values (primitives, Strings, and so on) `<property/>`元素的属性`value`表现为字符串,spring的[conversion service](https://docs.spring.io/spring/docs/5.0.6.RELEASE/spring-framework-reference/core.html#core-convert-ConversionService-API) 会把它转为正确的类型. ~~~xml <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <!-- 调用 setDriverClassName(String)把值注入 --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mydb"/> <property name="username" value="root"/> <property name="password" value="masterkaoli"/> </bean> ~~~ 下面使用[p-namespace](https://docs.spring.io/spring/docs/5.0.6.RELEASE/spring-framework-reference/core.html#beans-p-namespace)简写 ~~~xml <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 id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/mydb" p:username="root" p:password="masterkaoli"/> </beans> ~~~ 上面的方式很简洁,但是在运行时容易有错别字,建议使用带帮助功能的IDE,如 IntelliJ IDEA 或 the Spring Tool Suite. 你还可以配置java.util.Properties实例 ~~~xml <bean id="mappings" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <!-- java.util.Properties类型 --> <property name="properties"> <value> jdbc.driver.className=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mydb </value> </property> </bean> ~~~ ### The idref element idref元素只是一种防错的方式,可以将容器中另一个bean的id(字符串值 - 不是引用)传递给`<constructor-arg />`或`<property />`元素。 ~~~xml <bean id="theTargetBean" class="..."/> <bean id="theClientBean" class="..."> <property name="targetName"> <idref bean="theTargetBean"/> </property> </bean> ~~~ 上面的方式和下面是等效的 ~~~xml <bean id="theTargetBean" class="..." /> <bean id="client" class="..."> <property name="targetName" value="theTargetBean"/> </bean> ~~~ 第一种方式比第二种方式更好一点,因为idref允许spring在部署的时候去校验bean是否存在.第二种方式value只有在bean实例化是才会校验 > idref元素的属性local从4.0开始不再支持了.因为local不支持规则bean之外的引用,要升级到4.0,需要把属性local改为bean. > 元素<idref/>配置的地方带来一个价值就是在`ProxyFactoryBean `配置的spring AOP拦截器,当指定拦截器名称时,使用`<idref/>`避免拼写错误实例的id. ## References to other beans (collaborators) 元素`<constructor-arg/>` 或 `<property/>`的子元素`<ref/>`指向了另一个bean.`<ref/>`标签的属性`bean`指向目标bean的id或name值. ~~~xml <ref bean="someBean"/> ~~~ 使用`parent`属性指定引用的父容器内的bean.当你需要通过代理包装父容器的bean时,名称保持一致. ~~~xml <!--父容器--> <bean id="accountService" class="com.foo.SimpleAccountService"> </bean> ~~~ ~~~xml <!--子容器--> <bean id="accountService" <!-- 和父容器的名字一样 --> class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <ref parent="accountService"/> <!-- 引用父容器的bean --> </property> </bean> ~~~ ## Inner beans `<property/>` 或 `<constructor-arg/>`内部的`<bean/>`定义为内部类 ~~~xml <bean id="outer" class="..."> <!-- 在内部定义bean --> <property name="target"> <bean class="com.example.Person"> <!-- 这是内部类 --> <property name="name" value="Fiona Apple"/> <property name="age" value="25"/> </bean> </property> </bean> ~~~ 内部类不需要定义id和name,定义了也不起作用,包括范围也无效,内部类是匿名的且通过外部类来创建,不可能把内部类注入到其他bean里. ## Collections 元素`<list/>, <set/>, <map/>, <props/> `分别对应java的集合`List, Set, Map, Properties` ~~~xml <bean id="moreComplexObject" class="example.ComplexObject"> <!-- 调用setAdminEmails(java.util.Properties) --> <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> <!-- 调用setSomeList(java.util.List) --> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource" /> </list> </property> <!-- 调用setSomeMap(java.util.Map) --> <property name="someMap"> <map> <entry key="an entry" value="just some string"/> <entry key ="a ref" value-ref="myDataSource"/> </map> </property> <!--调用setSomeSet(java.util.Set) --> <property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource" /> </set> </property> </bean> ~~~ ### Collection merging spring支持集合的合并,元素`<list/>, <set/>, <map/>, <props/> `可以嵌套元素`<list/>, <set/>, <map/>, <props/> `子元素的值会覆盖父元素的值 ~~~xml <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"> <!-- 在子集合上指定合并 --> <props merge="true"> <prop key="sales">sales@example.com</prop> <prop key="support">support@example.co.uk</prop> </props> </property> </bean> <beans> ~~~ 当`child`实例化后,会拥有`parent`的属性,并且覆盖了`support`的值,最终为 ~~~properties administrator=administrator@example.com sales=sales@example.com support=support@example.co.uk ~~~ 其他集合元素`<list/>, <set/>, <map/> `是类似的,注意list会有order属性. ### Limitations of collection merging 集合合并,只能在子元素上设置,并且相同类型的才可以合并,否则会有异常. ### Strongly-typed collection 在java5之后,可以强制限制集合的允许的类型,如果bean注入强类型的集合,可以利用spring的类型转换把集合转成对应的类型,然后在注入bean. ~~~java public class Foo { private Map<String, Float> accounts; public void setAccounts(Map<String, Float> accounts) { this.accounts = accounts; } } ~~~ ~~~xml <beans> <bean id="foo" class="x.y.Foo"> <property name="accounts"> <map> <entry key="one" value="9.99"/> <entry key="two" value="2.75"/> <entry key="six" value="3.99"/> </map> </property> </bean> </beans> ~~~ ## Null and empty string values spring对待空参数或属性是空字符串("") ~~~xml <bean class="ExampleBean"> <property name="email" value=""/> </bean> ~~~ 上面的配置,等效如下java代码 ~~~java exampleBean.setEmail(""); ~~~ 元素`<null/>`处理null值 ~~~xml <bean class="ExampleBean"> <property name="email"> <null/> </property> </bean> ~~~ 上面配置等效如下java代码 ~~~java exampleBean.setEmail(null); ~~~ ## XML shortcut with the p-namespace ## XML shortcut with the c-namespace ## Compound property names