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 + '\'' +
'}';
}
}
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="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>
<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 +
'}';
}
}
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>
<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();
}
}
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();
}
}
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>
<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
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());
}
}
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'}}
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());
}
}
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>
项目结构图: