一、依赖注入方式

对于spring配置一个bean时,如果需要给该bean提供一些初始化参数,则需要通过依赖注入方式,所谓的依赖注入就是通过spring将bean所需要的一些参数传递到bean实例对象的过程,spring的依赖注入有3种方式:

·使用属性的setter方法注入 ,这是最常用的方式;
·使用构造器注入;
·使用Filed注入(用于注解方式)。

1.使用属性注入

属性注入即通过setXxx()方法注入Bean的属性值或依赖对象,由于属性注入方式具有可选择性和灵活性高的优点,因此属性注入是实际应用中最常采用的注入方式。

<bean id=”……” class=”……”>
<property name=”属性1” value=”……”/>
<property name=”属性2” value=”……”/>
……
</bean>

属性注入要求Bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter方法。Spring先调用Bean的默认构造函数实例化Bean对象,然后通过反射的方式调用Setter方法注入属性值。来看一个简单的例子。

package com.spring.model;

public class Car {

    private int maxSpeed;
private String brand;
private double price; public int getMaxSpeed() {
return maxSpeed;
}
//一定要写被注入对象的set方法
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
} public void run(){
System.out.println("brand:"+brand+",maxSpeed:"+maxSpeed+",price:"+price);
}
}

Car类中定义了3个属性,并分别提供了对应的Setter方法。(注:默认构造函数是不带参的构造函数。Java语言规定如果类中没有定义任何构造函数,则JVM自动为其生成一个默认的构造函数。反之,如果类中显示定义了构造函数,则JVM不会为其生成默认的构造函数。所以假设Car类中显示定义了一个带参的构造函数,如public Car(String brand),则需要同时提供一个默认构造函数public Car(),否则使用属性注入时将抛出异常。)
下面在Spring配置文件中对Car进行属性注入:

<!-- 属性注入 -->
<bean id="car" class="com.spring.model.Car">
<property name="maxSpeed" value="200"></property>
<property name="brand" value="红旗CA72"></property>
<property name="price" value="200000.00"></property>
</bean>

在上述代码中配置了一个Bean,并为该Bean的3个属性提供了属性值。具体来说,Bean的每一个属性对应一个<property>标签,name为属性的名称,在Bean实现类中拥有与其对应的Setter方法:maxSpeed对应setMaxSpeed(),brand对应setBrand()。
     需要指出的是:Spring只会检查Bean中是否有对应的Setter方法,至于Bean中是否有对应的属性变量则不做要求。例如配置文件中<property name="brand"/>的属性配置项仅要求Car类中拥有setBrand()方法,但Car类不一定要拥有brand成员变量。

测试方法:

/**
* 属性注入
*/
@Test
public void test(){
//读取配置文件
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
//获取bean的实例
Car car=(Car) ctx.getBean("car");
car.run();
}

 2.构造函数注入

构造函数注入是除属性注入之外的另一种常用的注入方式,它保证一些必要的属性在Bean实例化时就得到设置,并且确保了Bean实例在实例化后就可以使用。
使用方式:
第一,在类中,不用为属性设置setter方法,但是需要生成该类带参的构造方法。
第二,在配置文件中配置该类的bean,并配置构造器,在配置构造器中用到了<constructor-arg>节点,该节点有四个属性:
· index是索引,指定注入的属性,从0开始;
· type是指该属性所对应的类型;
· ref 是指引用的依赖对象;
· value 当注入的不是依赖对象,而是基本数据类型时,就用value;

(1)按类型匹配入参

如果任何可用的Car对象都必须提供maxSpeed、brand和price的值,使用属性注入方式只能人为在配置时提供保证,而无法在语法级提供保证,这时通过构造函数注入就可以很好地满足这一要求。使用构造函数注入的前提是Bean必须提供带参的构造函数,下面为Car提供一个可设置maxSpeed、brand和price属性的构造函数。

package com.spring.model;

public class Car {

    private int maxSpeed;
private String brand;
private double price; //带参构造方法
public Car(int maxSpeed,String brand, double price){
this.maxSpeed=maxSpeed;
this.brand=brand;
this.price=price;
} public void run(){
System.out.println("brand:"+brand+",maxSpeed:"+maxSpeed+",price:"+price);
}
}

构造函数注入的配置方式和属性注入方式的配置有所不同,在spring配置文件中使用构造函数注入装配这个Car Bean。

<!-- 构造函数注入(按类型匹配) -->
<bean id="car1" class="com.spring.model.Car">
<constructor-arg type="int" value="300"></constructor-arg>
<constructor-arg type="java.lang.String" value="宝马"></constructor-arg>
<constructor-arg type="double" value="300000.00"></constructor-arg>
</bean>

在<constructor-arg>的元素中有一个type属性,它表示构造函数中参数的类型,为spring提供了判断配置项和构造函数入参对应关系的“信息”。

(2)按索引匹配入参

我们知道,Java语言通过入参的类型及顺序区分不同的重载方法,对于上面代码中的Car类,Spring仅通过type属性指定的参数类型就可以知道“宝马”对应String类型的brand入参,而“300000.00”对应double类型的price入参。但是,如果Car构造函数3个入参的类型相同,仅通过type就无法确定对应关系了,这时需要通过入参索引的方式进行确定。
为了更好地演示按索引匹配入参的配置方式,特意对Car构造函数进行一下调整。

public Car(String brand, String corp,double price){
this.brand=brand;
this.corp=corp;
this.price=price;
}

brand和corp的入参类型都是String,所以String将无法确定type为String的<constructor-arg>到底对应的是brand还是corp。但是,通过显示指定参数的索引能够消除这种不确定性,如下所示。

<!-- 构造函数注入(按索引匹配) -->
<bean id="car2" class="com.spring.model.Car">
<!-- 注意索引从0开始 -->
<constructor-arg index="0" value="宝马"></constructor-arg>
<constructor-arg index="1" value="中国一汽"></constructor-arg>
<constructor-arg index="2" value="300000.00"></constructor-arg>
</bean>

构造函数第一个参数索引为0,第二个为1,以此类推,因此很容易知道“宝马”对应brand入参,而“中国一汽”对应corp入参。

(3)联合使用类型和索引匹配入参
     有时需要联合使用type和index才能确定匹配项和构造函数入参的对应关系,看下面的代码。

public Car(String brand, String corp,double price){
this.brand=brand;
this.corp=corp;
this.price=price;
} public Car(String brand, String corp,int maxSpeed){
this.brand=brand;
this.corp=corp;
this.maxSpeed=maxSpeed;
}

这里,Car拥有两个重载的构造函数,它们都有三个入参。针对这种情况,按照入参索引的配置方式又难以满足要求了,这时需要联合使用<constructor-arg>的type和index才能解决问题,看下面代码。

<!-- 构造函数注入(通过入参类型和位置索引确定对应关系) -->
<!-- 对应public Car(String brand, String corp,int maxSpeed)构造函数 -->
<bean id="car3" class="com.spring.model.Car">
<constructor-arg index="0" type="java.lang.String" value="奔驰"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="中国一汽"></constructor-arg>
<constructor-arg index="2" type="int" value="200"></constructor-arg>
</bean>

对于上面的两个构造函数,如果仅通过index进行配置,Spring将无法确定第3个入参配置项究竟是对应int的maxSpeed还是double的price,采用索引匹配时,真正引起歧义的地方在于第3个入参,因此仅需要明确指定第3个入参的类型就可以取消歧义了。所以在上面的代码中,第1个和第2个<constructor-arg>元素的type属性可以去除。
      对于由于参数数目相同而类型不同所引起的潜在配置歧义问题,Spring容器可以正确启动且不会给出报错信息,它将随机采用一个匹配的构造函数实例化Bean,而被选择的构造函数可能并不是用户所希望的。因此,必须特别谨慎,以避免潜在的错误。

 3.使用字段(Filed)注入(用于注解方式)

除了上面讲到的使用属性的setter方法或使用构造器方法来注入依赖对象,还有一种注入依赖对象的方法,就是使用注解。

来看一个例子,首先不使用注解的方式。

新建一个业务接口:

package com.spring.service;

public interface ICommonService {

    public void add();
}

实现类:

package com.spring.service.impl;

import com.spring.dao.ICommonDao;
import com.spring.service.ICommonService; public class CommonServiceImpl implements ICommonService{ private ICommonDao commonDao; // 依赖注入DAO组件所需的setter方法
public void setCommonDao(ICommonDao commonDao) {
this.commonDao = commonDao;
} public void add(){
commonDao.add();
}
}

dao层接口:

package com.spring.dao;

public interface ICommonDao {
public void add();
}

实现类:

package com.spring.dao.impl;

import com.spring.dao.ICommonDao;

public class CommonDaoImpl implements ICommonDao{

    public void add(){
System.out.println("enter add!");
}
}

配置文件:

<bean id="commonDao" class="com.spring.dao.impl.CommonDaoImpl"></bean>
<bean id="commonService" class="com.spring.service.impl.CommonServiceImpl">
<!-- 注入持久化访问所需的DAO组件 -->
<property name="commonDao" ref="commonDao"/>
</bean>

以上是不使用注解的方式注入依赖对象(使用属性注入),下面来看一下使用注解为某个bean注入依赖对象。

(1)首先,在Spring容器的配置文件applicationContext.Xml文件中配置以下信息,该信心是一个Spring配置文件的模板.

<?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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
"> </beans>

注意:只有配置了紫色部分的行才可以引入注解的命名空间,否则报错。以上的配置隐式的注册了多个对注释进行解析的处理器:AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor等。

(2)其次,在配置文件中打开<context:annotation-config>节点,告诉Spring容器可以用注解的方式注入依赖对象;其在配置文件中的代码如下:

<beans>

……

<context:annotation-config></context:annotation-config>

……

</beans>

(3)第三,在配置文件中配置bean对象,如下:

<bean id="commonDao" class="com.spring.dao.impl.CommonDaoImpl"></bean>
<bean id="commonService" class="com.spring.service.impl.CommonServiceImpl"></bean>

(4)第四,在需要依赖注入的类中(本例中是CommonServiceImpl),声明一个依赖对象,不用生成该依赖对象的setter方法,并且为该对象添加注解。

修改业务层实现类CommonServiceImpl

package com.spring.service.impl;

import javax.annotation.Resource;
import com.spring.dao.ICommonDao;
import com.spring.service.ICommonService; public class CommonServiceImpl implements ICommonService{ @Resource(name="commonDao")
private ICommonDao commonDao; // // 依赖注入DAO组件所需的setter方法
// public void setCommonDao(ICommonDao commonDao) {
// this.commonDao = commonDao;
// } public void add(){
commonDao.add();
}
}

其中,在Java代码中可以使用@Autowired或@Resource注解方式进行Spring的依赖注入。两者的区别是:@Autowired默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。

比如:我们用@Autowired为上面的代码ICommonDao接口的实例对象进行注解,它会到Spring容器中去寻找与ICommonDao对象相匹配的类型,如果找到该类型则将该类型注入到commonDao字段中;

如果用@Resource进行依赖注入,它先会根据指定的name属性去Spring容器中寻找与该名称匹配的类型,例如:@Resource(name="commonDao"),如果没有找到该名称,则会按照类型去寻找,找到之后,会对字段commonDao进行注入。

使用注解注入依赖对象不用再在代码中写依赖对象的setter方法或者该类的构造方法,并且不用再配置文件中配置大量的依赖对象,使代码更加简洁,清晰,易于维护。

在Spring IOC编程的实际开发中推荐使用注解的方式进行依赖注入。

二、依赖注入——自动装配

在应用中,我们常常使用<ref>标签为JavaBean注入它依赖的对象,同时也Spring为我们提供了一个自动装配的机制,在定义Bean时,<bean>标签有一个autowire属性,我们可以通过指定它来让容器为受管JavaBean自动注入依赖对象。

自动装配是在配置文件中实现的,如下:<bean id="***" class="***" autowire="byType">

只需要配置一个autowire属性即可完成自动装配,不用再配置文件中写<property>,但是在类中还是要生成依赖对象的setter方法。

<bean>的autowire属性有如下六个取值,他们的说明如下

1.No:即不启用自动装配。Autowire默认的值。默认情况下,需要通过"ref"来装配bean,如下:

package com.lei.common;

public class Customer
{
private Person person; public Customer(Person person) {
this.person = person;
} public void setPerson(Person person) {
this.person = person;
}
//...
}
package com.lei.common;

public class Person
{
//...
}

配置文件:

<bean id="customer" class="com.lei.common.Customer">
<property name="person" ref="person" />
</bean>
<bean id="person" class="com.lei.common.Person" />

2.byName:按名称装配  可以根据属性的名称在容器中查询与该属性名称相同的bean,如果没有找到,则属性值为null。假设Boss类中有一个名为car的属性,如果容器中刚好有一个名为car的Bean,Spring就会自动将其装配给Boss的car属性。

根据属性Property的名字装配bean,这种情况,Customer设置了autowire="byName",Spring会自动寻找与属性名字“person”相同的bean,找到后,通过调用setPerson(Person person)将其注入属性。

<bean id="customer" class="com.lei.common.Customer" autowire="byName" />
<bean id="person" class="com.lei.common.Person" />

如果根据 Property name找不到对应的bean配置,如下:

<bean id="customer" class="com.lei.common.Customer" autowire="byName" />
<bean id="person_another" class="com.lei.common.Person" />

Customer中Property名字是person,但是配置文件中找不到person,只有person_another,这时就会装配失败,运行后,Customer中person=null。

3.byType:按类型装配  可以根据属性类型,在容器中寻找该类型匹配的bean,如有多个,则会抛出异常,如果没有找到,则属性值为null。假设Boss类中有一个Car类型的属性,如果容器中刚好有一个Car类型的Bean,Spring就会自动将其装配给Boss的这个属性。

根据属性Property的数据类型自动装配,这种情况,Customer设置了autowire="byType",Spring会总动寻找与属性类型相同的bean,找到后,通过调用setPerson(Person person)将其注入。

<bean id="customer" class="com.lei.common.Customer" autowire="byType" />
<bean id="person" class="com.lei.common.Person" />

如果配置文件中有两个类型相同的bean会怎样呢?如下:

<bean id="customer" class="com.lei.common.Customer" autowire="byType" />
<bean id="person" class="com.lei.common.Person" />
<bean id="person_another" class="com.lei.common.Person" />

一旦配置如上,有两种相同数据类型的bean被配置,将抛出UnsatisfiedDependencyException异常,见以下:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException:
所以,一旦选择了“byType”类型的自动装配,请确认你的配置文件中每个数据类型定义一个唯一的bean。

4.constructor:与byType方式相似,不同之处在与它应用于构造器参数,如果在容器中没有找到与构造器参数类型一致的bean,那么将抛出异常。(根据构造函数参数的数据类型,进行byType模式的自动装配。)

这种情况下,Spring会寻找与参数数据类型相同的bean,通过构造函数public Customer(Person person)将其注入。

<bean id="customer" class="com.lei.common.Customer" autowire="constructor" />
<bean id="person" class="com.lei.common.Person" />

5.autodetect:通过bean类的自省机制(introspection)来决定是使用constructor还是byType的方式进行自动装配。如果Bean有空构造器那么将采用“byType”自动装配方式,否则使用“constructor”自动装配方式。

这种情况下,Spring会先寻找Customer中是否有默认的构造函数,如果有相当于上边的"constructor"这种情况,用构造函数注入,否则,用"byType"这种方式注入,所以,此例中通过调用public Customer(Person person)将其注入。

<bean id="customer" class="com.lei.common.Customer" autowire="autodetect" />
<bean id="person" class="com.lei.common.Person" />

6.default:由上级标签<beans>的default-autowire属性确定。

注意:在配置bean时,<bean>标签中Autowire属性的优先级比其上级标签高,即是说,如果在上级标签中定义default-autowire属性为byName,而在<bean>中定义为byType时,Spring IoC容器会优先使用<bean>标签的配置。

小结:使用自动装配,配置文件简洁了许多。但是,自动装配并不是十全十美的,我们不论是使用byName还是byType的方法,Spring不一定就能很准确的为我们找到JavaBean依赖的对象。在这种情况下,你务必遵守javabean的命名规范,另外,如果使用自动装配,Spring配置文件的可读性也大大降低,我们不能很容易的看出个bean之间的依赖关系,这也在一定程度上降低了程序可维护性;也容易造成潜在的错误,比如说通过byName来装配,如果将属性 名字改了后,Spring就不会将其自动装配给Bean的属性了。

因此在使用自动装配时,应当权衡利弊,合理的与ref的方法相结合,尽量在降低工作量的同时,保证应用的可维护度。但是spring的reference还是不推荐在定义中用这个功能。

不是所有类型都能自动装配,不能自动装配的数据类型:Object、基本数据类型(Date、CharSequence、Number、URI、URL、Class、int)等。

三、注入参数详解

·注入常量

注入常量是依赖注入中最简单的。配置方式如下所示:

<property name="message" value="Hello World!"/>

<property name="index"><value>1</value></property>

以上两种方式都可以,从配置来看第一种更简洁。注意此处“value”中指定的全是字符串,由Spring容器将此字符串转换成属性所需要的类型,如果转换出错,将抛出相应的异常。

·注入集合类型

Java.util包中的集合类是最常用的数据结构类型,主要包括List、Set、Map、Properties,Spring为这些集合类型属性提供了专门的配置元素标签。

1.List:需要使用<list>标签来配置注入。

新建一个Boss类,并在类中添加一个List类型的favorites属性。

package com.spring.model;

import java.util.List;

public class Boss {

    private List favorites;

    public List getFavorites() {
return favorites;
} public void setFavorites(List favorites) {
this.favorites = favorites;
} public void print(){
System.out.println(favorites);
}
}

对应Spring中的配置片段如下所示:

<!-- 注入List类型属性 -->
<bean id="boss" class="com.spring.model.Boss">
<property name="favorites">
<list>
<value>看报</value>
<value>赛车</value>
<value>高尔夫</value>
</list>
</property>
</bean>

List属性既可以通过<value>注入字符串,也可以通过<ref>注入容器中的其他Bean。

2.Set:需要使用<set>标签来配置注入,其配置参数及含义和<lsit>标签完全一样,具体配置例子如下:

<bean id=”……” class=”……”>
<property name="……">
<set>
<value>value1</value>
<value>value2</value>
……
</set>
</property>
</bean>

3.Map:需要使用<map>标签来配置注入,其属性“key-type”和“value-type”分别指定“键”和“值”的数据类型。

在Boss类中添加一个Map类型的jobs属性。

package com.spring.model;

import java.util.List;
import java.util.Map; public class Boss { private Map jobs; public Map getJobs() {
return jobs;
} public void setJobs(Map jobs) {
this.jobs = jobs;
} public void print1(){
System.out.println(jobs);
}
}

在配置文件中可以通过以下方式为jobs属性提供配置值。

<!-- 注入Map类型属性 -->
<bean id="boss1" class="com.spring.model.Boss">
<property name="jobs">
<map>
<entry key="AM" value="会见客户" />
<entry key="PM" value="公司内部会议" />
</map>
</property>
</bean>

其中<map>表示Map注入,<entry>表示键值对,<key>表示键数据,<value>表示键所对应的值数据。

4.Properties:需要使用<props>标签来配置注入,键和值类型必须是String,不能变,子标签<prop key=”键”>值</prop>来指定键值对。

Properties类型其实可以看成是Map类型的特例。Map元素的键和值可以是任何类型的对象,而Properties属性的键和值都只能是字符串。为Boss添加一个Properties类型的mails属性。

package com.spring.model;

import java.util.List;
import java.util.Map;
import java.util.Properties; public class Boss { private Properties mails; public Properties getMails() {
return mails;
} public void setMails(Properties mails) {
this.mails = mails;
} public void print2(){
System.out.println(mails);
}
}

下面的配置片段为mails提供了配置。

<!-- 注入Properties类型属性 -->
<bean id="boss2" class="com.spring.model.Boss">
<property name="mails">
<props>
<prop key="jobMail">john-office@163.com</prop>
<prop key="lifeMail">john-life@163.com</prop>
</props>
</property>
</bean>

因为Properties键值对只能是字符串,因此其配置比Map的配置要简单一些,注意值得配置没有<value>子元素标签。

·引用其他Bean

Spring IOC容器中定义的Bean可以相互引用,IOC容器则充当“红娘”的角色。下面在Boss类中添加一个Car类型的属性。

package com.spring.model;

import java.util.List;
import java.util.Map;
import java.util.Properties; public class Boss { private Car car;
//设置car属性
public void setCar(Car car) {
this.car = car;
} public void print3(){
System.out.println(car.getBrand()+"----"+car.getPrice()+"----"+car.getMaxSpeed());
}
}

boss的Bean通过<ref>元素引用car Bean,建立起boss对car的依赖。

<bean id="car" class="com.spring.model.Car">
<property name="maxSpeed" value="200"></property>
<property name="brand" value="红旗CA72"></property>
<property name="price" value="200000.00"></property>
</bean>
<!-- 通过ref元素引用bean -->
<bean id="boss3" class="com.spring.model.Boss">
<property name="car">
<!--引用上面定义的car Bean-->
<ref bean="car"></ref>
</property>
</bean>

<ref>元素可以通过以下3个属性引用容器中的其他Bean。
·  bean:通过该属性可以引用同一容器或父容器的Bean,这是最常见的形式。

·  local:通过该属性只能引用同一配置文件中定义的Bean,它可以利用XML解析器自动检验引用的合法性,以便在开发编写配置时能够及时发现并纠正配置的错误。

·  parent:引用父容器中的Bean,如<ref parent="car">的配置说明car的Bean是父容器中的Bean。

为了说明子容器对父容器中Bean的引用,来看一个具体的例子。假设有两个配置文件beans1.xml和beans2.xml,其中beans1.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
"> <!--在父容器中定义的car -->
<bean id="car" class="com.spring.model.Car">
<property name="brand" value="红旗CA72"></property>
<property name="maxSpeed" value="200"></property>
<property name="price" value="200000.00"></property>
</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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
"> <!--1.该Bean和父容器中的car Bean具有相同的id -->
<bean id="car" class="com.spring.model.Car">
<property name="brand" value="吉利CT5"></property>
<property name="maxSpeed" value="100"></property>
<property name="price" value="100000.00"></property>
</bean>
<bean id="boss" class="com.spring.model.Boss">
<property name="car">
<!--引用父容器中的car,而非1处定义的Bean,如果采用<ref bean="car" />将引用本容器1处的car -->
<ref parent="car"></ref>
</property>
</bean>
</beans>

在beans1.xml中配置了一个car Bean,在beans2.xml中也配置了一个car Bean。分别通过父子容器加载beans1.xml和beans2.xml,beans2.xml中的boss通过<ref parent="car">将引用到父容器中的car。下面是分别加载beans1.xml和beans2.xml配置文件的代码。

/**
* 引用父容器中的bean
*/
@Test
public void test9(){
//父容器
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("引用父容器中的bean");
System.out.println(boss.getCar().toString());
}

运行这段代码,控制台中打印出以下的信息。

引用父容器中的bean
brand:红旗CA72/maxSpeed:200/price:200000.0

Spring系列之依赖注入的方式的更多相关文章

  1. Spring学习(三)——Spring中的依赖注入的方式

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

  2. spring学习 五 依赖注入的方式

    依赖注入有两种方式: 1 构造注入,如果<bean>标签下使用<contructor-arg>,则是构造注入 2 setter注入,就是调用setter方法注入,如果<b ...

  3. JavaEE开发之Spring中的依赖注入与AOP

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  4. JavaEE开发之Spring中的依赖注入与AOP编程

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  5. 极简SpringBoot指南-Chapter02-Spring依赖注入的方式

    仓库地址 w4ngzhen/springboot-simple-guide: This is a project that guides SpringBoot users to get started ...

  6. Spring 依赖注入的方式

    Spring 支持3中依赖注入的方式 1.属性注入  通过setter 方法注入Bean的属性或依赖的对象. <bean id = " " class = " &q ...

  7. spring六种种依赖注入方式

    平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程 ...

  8. spring 四种依赖注入方式以及注解注入方式

    平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程 ...

  9. Spring(八):Spring配置Bean(一)BeanFactory&ApplicationContext概述、依赖注入的方式、注入属性值细节

    在Spring的IOC容器里配置Bean 配置Bean形式:基于xml文件方式.基于注解的方式 在xml文件中通过bean节点配置bean: <?xml version="1.0&qu ...

随机推荐

  1. WPF 提示框、确认框、确认输入框

    1.提示框 分为提示.异常.失败.成功几种类型 方法: /// <summary> /// 弹出提示 /// 标题:提示 /// </summary> /// <para ...

  2. shell中各种括号的作用()、(())、[]、[[]]、{}

    一.小括号,圆括号() 1.单小括号 ()    ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有 ...

  3. ubuntu 12.04下安装openldap,slapd.conf找不到的解决方法

    https://help.ubuntu.com/12.04/serverguide/openldap-server.html ubuntu安装openldap经历了一系列挫折,网上找了半天资料都是一模 ...

  4. MySQL server has gone away报错原因分析/

    在平时和开发的交流 以及 在论坛回答问题的或称中会发现这个问题被问及的频率非常高. 程序中报错: MySQL server has gone away 是什么意思? 如何避免? 因此,感觉有必要总结一 ...

  5. 【小白的CFD之旅】02 江小白

    虽然已经是9月份了,但是西南地区的湿热天气依然将小白热成了狗.独自一个人来到这号称天府之国的西南城市,小白却一点都没感受到这天府之国的友好.毒辣的阳光像利剑一样照射到身上,让人感觉如在蒸笼中一样.从炎 ...

  6. JAVA中内部类和同文件非内部类的总结

    java文件的顶层类(即非其它类的内部类),可见范围只有public和非public(包内可见)2种,不能用private或protected修饰.1个Java文件只能有一个public类,且必须与文 ...

  7. Markdown 完全指南

    概述 Markdown 是一种用于网络文本书写的轻量级标记语言,广泛用于个人 blog.github.wiki 中.其实浏览器并不能识别 Markdown 的语法,但许多 blog.wiki 平台以及 ...

  8. Let it go.Let it be.Keep it up!

    第三份工作仅仅持续了三个月,今天是last day. 虽然时间很短,但也是经历一场,认识了一些人,知道了一些事. 来去匆匆,难免有一点遗憾,还有一点愧疚. 只能放下,顺其自然,继续努力!

  9. Java程序设计之正则表达式

    正则表达式平时在用到字符串处理的时候是比较常用的,个人觉得不需要刻意的去理解,用的话把文档拿出来查一下就好了,下面给个链接 http://www.php100.com/manual/Javascrip ...

  10. C/C++编程语言学习资料尽收眼底 电子书+视频教程

    Visual C++(VC/MFC)学习电子书及开发工具下载请看这里 史无前例的网络最全最强C/C++资料索引: C/C++编程语言学习资料尽收眼底 电子书+视频教程 VC++/MFC(VC6)开发技 ...