Spring依赖注入方式

1. 构造器注入

Address.java
package cn.springtest.ioc;
public class Address {
private String country;
private String city;
public Address() {
}
public Address(String country, String city) {
this.country = country;
this.city = city;
}
// public String getCountry() {
// return country;
// }
// public void setCountry(String country) {
// this.country = country;
// }
// public String getCity() {
// return city;
// }
// public void setCity(String city) {
// this.city = city;
// }
@Override
public String toString() {
return "Address{" +
"country='" + country + '\'' +
", city='" + city + '\'' +
'}';
}
}

applicationContext.xml关于address的构造器注入配置
    <!--默认构造器注入-->
    <bean name="addressDefault" class="cn.springtest.ioc.Address">
    </bean>

<!--构造器注入-->
    <bean name="address" class="cn.springtest.ioc.Address">
        <constructor-arg name="country" value="China"/>
        <constructor-arg name="city" value="ShangHai"/>
    </bean>
Tips:使用哪种构造器注入时哪种构造方法必须存在,例如:使用默认构造器(无参数的构造器)注入时,如果不存在该构造器(如果类作者重载了构造器,且没有显示声明默认构造器),则Spring将抛出一个异常。其实用一些编辑器时,它都会帮你检查出错误的。

2. setter方法注入

Person .java
package cn.springtest.ioc;
public class Person {
    private String firstName;
    private String lastName;
    private Address homeAddress;
//    public Person() {
//    }
//    public Person(String firstName, String lastName, Address homeAddress) {
//        this.firstName = firstName;
//        this.lastName = lastName;
//        this.homeAddress = homeAddress;
//    }
//    public String getFirstName() {
//        return firstName;
//    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
//    public String getLastName() {
//        return lastName;
//    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
//    public Address getHomeAddress() {
//        return homeAddress;
//    }
    public void setHomeAddress(Address homeAddress) {
        this.homeAddress = homeAddress;
    }
    @Override
    public String toString() {
        return "Person{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", homeAddress=" + homeAddress +
                '}';
    }
}
applicationContext.xml关于person的setter方法注入配置
  <bean name="person" class="cn.springtest.ioc.Person">
        <property name="firstName" value="Na"/>
        <property name="lastName" value="Luo"/>
        <property name="homeAddress" ref="address"/>
    </bean>
Tips:Person的属性的set方法必须存在,否则编译器都会检查出错误的

3. 静态工厂注入

StaticFactoryClass.java
package cn.springtest.ioc;
public class StaticFactoryClass {
    public static final Person getStaticFactoryPerson(){
        return new Person();
    }
}
applicationContext.xml关于person的静态工厂方法注入配置
<bean id="personStatic" class="cn.springtest.ioc.StaticFactoryClass" factory-method="getStaticFactoryPerson"></bean>

4. 实例工厂注入

package cn.springtest.ioc;
public class InstanceFactoryClass {
    public Person getInstanceFactoryPerson(){
        return new Person();
    }
}

applicationContext.xml关于person的实例工厂方法注入配置
    <bean id="instanceFactory" class="cn.springtest.ioc.InstanceFactoryClass"></bean>
    <bean id="personInstance" factory-bean="instanceFactory" factory-method="getInstanceFactoryPerson"></bean>

测试

SpringTest .java测试文件
package cn.springtest.ioc;
import cn.springtest.ioc.Address;
import cn.springtest.ioc.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:applicationContext.xml","classpath:springmvc.xml"})
public class SpringTest {
    @Autowired
    private Address address;
    @Autowired
// @Qualifier("person")
    private Person person;
    @Test
    public void testSpring() throws Exception{
        System.out.println(address.toString());
        System.out.println(person.toString());
    }
}

测试结果:
Address{country='China', city='ShangHai'}
Person{firstName='Na', lastName='Luo', homeAddress=Address{country='China', city='ShangHai'}}

补充说明:
1.@Autowired和创建一个ApplicationContext对象都适用于以上四种注入方式。
2. @Autowired是byType方式,当有多个类型相同的bean时需要使用@Qualifier("person"),否则会报错;但是当刚好有一个bean名称与变量名相同时会自动匹配相同bean名称的那个,此时可以不需@Qualifier。

BeanTest .java
package cn.springtest.ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class BeanTest {
    public static void main(String[] args) {
//        ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
        ApplicationContext context = new FileSystemXmlApplicationContext("src/main/resources/applicationContext.xml");
        Person person = context.getBean("personInstance", Person.class);
        person.setFirstName("luona");
        System.out.println(person.toString());
    }
}
测试结果:
Person{firstName='luona', lastName='null', homeAddress=null}

补充说明:
Spring支持XML或注解两种配置方式。此外,还需要创建一个ApplicationContext对象,代表一个Spring控制反转容器,org.springframework.context.ApplicationContext接口有多个实现,包括C1assPathXmlApplicationContext和FileSystemXmlApplicationContext。这两个实现都需要至少一个包含beans信息的XML文件。C1assPathXmlApplicationContext尝试在类加载路径中加载配置文件,而FileSystemXmlApplicationContext则从文件系统中加载。

附加

springmvc.xml配置:
<!-- 包的自动扫描 -->
<context:component-scan base-package="cn.springtest"></context:component-scan>

项目结构图:
Spring依赖注入方式