依赖注入 有三种方式,本文只学习下属性注入.
package com.spring.model; public class Car { /** * 系统为自动我们提供一个无参的构造方法 */ private String brand; private String color; private int maxSpeed; public void setBrand(String brand) { this.brand = brand; } public void setColor(String color) { this.color = color; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } }
<bean id="car" class="com.spring.model.Car" > <property name="maxSpeed"><value>200</value></property> <property name="brand"><value>红旗CAT2</value> </property> <property name="color"><value>红色</value></property> </bean>我们配置了一个Car Bean,并为该Bean的三个属性提供了属性值。具体来说,Bean的每一个属性对应一个<property>标签,name为属性的名称,在Bean实现类中拥有与其对应的Setter方法:maxSpeed对应setMaxSpeed。
package com.spring.model; public class Boss { private Car car=new Car(); public Car getCar() { return car; }
//设置Car属性 public void setCar(Car car) { this.car = car; }
.......... }
<!-- 1 car bean --> <bean id="car" class="com.spring.model.Car" /> <bean id="boss" class="com.spring.model.Boss"> <property name="car"> <!--2 引用1处定义的car bean --> <ref bean="car"/> </property> </bean><ref>元素可以通过以下三个属性引用容器中的其它Bean。
<?xml version="1.0" encoding="UTF-8"?> <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-3.0.xsd"> <!--1 在父容器定义的bean --> <bean id="car" class="com.spring.model.Car"> <property name="brand"> <value>红旗</value> </property> <property name="color" value="红色"/> <property name="maxSpeed" value="200"/> </bean> </beans>beans2.xml
<?xml version="1.0" encoding="UTF-8"?> <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-3.0.xsd"> <!--该bean和父容器的car bean具有相同的id--> <bean id="car" class="com.spring.model.Car"> <property name="brand"> <value>白旗CAR</value> </property> <property name="color" value="红色"/> <property name="maxSpeed" value="200"/> </bean> <bean id="boss" class="com.spring.model.Boss"> <property name="car"> <!-- 引用父容器的car,而非beans2.xml定义的car ,如果采用<ref bean="car" 则会引用本容器的car/> --> <ref parent="car"/> </property> </bean> </beans>在beans1.xml中定义了一个car bean,在beans2.xml也定义了一个car Bean。分别通过父子容器加载beans1.xml和beans2.xml,beans2.xml中的boss通过<ref parent="car">将引用到父容器中的car.
@Test public void test1(){ //父容器 ApplicationContext pFactory=new ClassPathXmlApplicationContext("beans1.xml"); //指定pFactory为该容器的父容器 ApplicationContext factory=new ClassPathXmlApplicationContext(new String[]{"beans2.xml"},pFactory); Boss boss=(Boss) factory.getBean("boss"); System.out.println(boss.getCar().getBrand()); }运行后结果如下:
红旗
<bean id="boss" class="com.spring.model.Boss"> <property name="car"> <bean class="com.spring.model.Car"> <property name="maxSpeed" value="200"/> <property name="color" value="白色"/> </bean> </property> </bean>内部bean和JAVA代码中匿名内部类很相似,即没有名字,也不能被其它bean引用,只能在声明处为外部bean提供实例注入。 内部bean即使提供了id、name、scope属性,也会被忽略,scope默认为prototype类型.
<property name="barnd"> <value><null/> </value> </property>
<bean id="boss2" class="com.spring.model.Boss"> <!-- 以原点的方式定义级别属性 --> <property name="car.brand" value="吉利Ct50"/> </bean>按照上面的配置,Spring将调用Boss.getCar.setBaran("吉利Ct50"),方法进行属性的注入操作。
package com.spring.model; import java.util.ArrayList; import java.util.List; public class Boss { private List favourites=new ArrayList(); public List getFavourites() { return favourites; } public void setFavourites(List favourites) { this.favourites = favourites; }}对应Spring 中的配置片段如下所示:
<bean id="boss" class="com.spring.model.Boss"> <property name="favourites"> <list> <value>看报</value> <value>赛车</value> <value>高尔夫</value> </list> </property> </bean>List属性既可以通过<value>注入字符串,也可以通过<ref>注入容器中其它的Bean.
<bean id="boss" class="com.spring.model.Boss"> <property name="favourites"> <set> <value>看报</value> <value>赛车</value> <value>高尔夫</value> </set> </property> </bean>Map
package com.spring.model; import java.util.HashMap; import java.util.Map; public class Boss { private Map jobs=new HashMap(); public Map getJobs() { return jobs; } public void setJobs(Map jobs) { this.jobs = jobs; } }在配置文件中,可以通过如下方式为jobs属性提供配置值:
<bean id="boss" class="com.spring.model.Boss"> <property name="jobs"> <map> <!-- Map 第一个元素 --> <entry> <key><value>AM</value></key> <value>会见客户</value> </entry> <!-- Map第二个元素 --> <entry> <key><value>PM</value></key> <value>公司内部会议</value> </entry> </map> </property> </bean>假设某一Map元素的键和值都是对象,则可以采取以下的配置方式:
<entry> <key><ref bean="keyBean"/> </key> <ref bean="valueBean"/> </entry>Properties
package com.spring.model; import java.util.Properties; public class Boss { private Properties mails=new Properties(); public Properties getMails() { return mails; } public void setMails(Properties mails) { this.mails = mails; } }下面的配置片段为mails提供了配置:
<bean id="boss" class="com.spring.model.Boss"> <property name="mails"> <props> <prop key="jobMail">[email protected]</prop> <prop key="lifeMail">[email protected]</prop> </props> </property> </bean>因为Properties键值对只能是字符串,因此其配置比Map的配置要简单一些,注意值的配置没有<value>子元素标签.
package com.spring.model; import java.util.HashMap; import java.util.Map; public class Boss { private Map<String,Integer> jobTime =new HashMap<String, Integer>(); public Map<String, Integer> getJobTime() { return jobTime; } public void setJobTime(Map<String, Integer> jobTime) { this.jobTime = jobTime; } }在Spring中的配置和非强类型集合相同:
<bean id="boss" class="com.spring.model.Boss"> <property name="jobTime"> <map> <entry> <key> <value>会见客户</value></key> <value>124</value> </entry> </map> </property> </bean>但Spring 容器在注入强类型集合时,会判断元素的类型,将设置值转换为对应的数据类型。如上面代码中的设置项124将被转换为Integer类型.
<?xml version="1.0" encoding="UTF-8"?> <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-3.0.xsd"> <!-- 父bean --> <bean id="parentBoss" abstract="true" class="com.spring.model.Boss"> <property name="favorites"> <set> <value>看报</value> <value>赛车</value> <value>高尔夫</value> </set> </property> </bean> <!-- 子bean --> <bean id="childBoss" class="com.spring.model.Boss" parent="parentBoss"> <property name="favorites"> <set merge="true"> <value>爬山</value> <value>游泳</value> </set> </property> </bean> </beans>在代码清单中,通过merge="true"属性指定子<bean>和父<bean>中的同名属性值进行合并,即子<bean>的favourites元素将最终拥有5个元素。如果设置merge="false",则不会和父<bean>同名集合属性进行合并,即子Bean的favourites属性集合只有两个元素.
@Test public void test2(){ ApplicationContext ctx=new ClassPathXmlApplicationContext("beans2.xml"); Boss boss=(Boss) ctx.getBean("childBoss"); Set set=boss.getFavorites(); System.out.println(set); }运行后结果如下:
[看报, 赛车, 高尔夫, 爬山, 游泳]