Spring容器提供了四种依赖注入方式,分别是构造器注入、Set注入、拓展方式注入(p、c namespace,可与前两种方式合并)、注解式依赖注入(补充)。下面直接通过简单的代码来展示他们的使用方法~
1.构造器注入
构造器注入方式要求实体类中必须要有有参构造方法,在Spring配置文件中bean中使用<constructor-arg…>标签进行属性赋值,该标签提供了index(有参构造方法参数位置,从0开始)和name(有参构造方法参数名)两种赋值方式。
这里使用三个简单的类Man、Wife、Money为例:
Class Money:
public class Money {
private int moneyNum;
public Money() {
}
public Money(int moneyNum) {
this.moneyNum = moneyNum;
}
public int getMoneyNum() {
return moneyNum;
}
public void setMoneyNum(int moneyNum) {
this.moneyNum = moneyNum;
}
@Override
public String toString() {
return "Money{" +
"moneyNum=" + moneyNum +
'}';
}
}
Class Wife:
public class Wife {
private String name;
private int age;
public Wife() {
}
public Wife(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Wife{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Class Man:
public class Man {
private String name;
private int age;
private Money money;
private Wife wife;
public Man() {
}
public Man(String name, int age, Money money, Wife wife) {
this.name = name;
this.age = age;
this.money = money;
this.wife = wife;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Money getMoney() {
return money;
}
public void setMoney(Money money) {
this.money = money;
}
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
@Override
public String toString() {
return "Man{" +
"name='" + name + '\'' +
", age=" + age +
", money=" + money +
", wife=" + wife +
'}';
}
}
applicationContext.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:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--DI之构造注入-->
<bean id="money" class="com.ndkj.pojo.Money">
<constructor-arg index="0" value="10001"/>
</bean>
<bean id="wife" class="com.ndkj.pojo.Wife">
<constructor-arg name="age" value="28"/>
<constructor-arg name="name" value="Taylor Swift"/>
</bean>
<bean id="man" class="com.ndkj.pojo.Man">
<constructor-arg name="age" value="20"/>
<constructor-arg name="money" ref="money"/>
<constructor-arg name="name" value="liu"/>
<constructor-arg name="wife" ref="wife"/>
</bean>
</beans>
测试类:
public class MyTest {
@Test
public void MyTest1(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Man man = context.getBean("man", Man.class);
System.out.println(man);
}
}
2.Set方式注入
Set方式要求实体类中必须要有Setter方法,凡是通过标签注入的属性统称为Set注入方式(包括数组、Map、Set等类型的注入,使用Set注入会默认调用类的无参构造函数。我们仍然使用上述的三个实体类来进行演示,唯一不同点在Spring中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"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--DI之Set注入-->
<bean id="money" class="com.ndkj.pojo.Money">
<property name="moneyNum" value="10000"/>
</bean>
<bean id="wife" class="com.ndkj.pojo.Wife">
<property name="name" value="Taylor Swift"/>
<property name="age" value="28"/>
</bean>
<bean id="man" class="com.ndkj.pojo.Man">
<property name="age" value="18"/>
<property name="name" value="huhu"/>
<property name="money" ref="money"/>
<property name="wife" ref="wife"/>
</bean>
</beans>
3.拓展方式注入(p、c nameSpace,前两种方式的另一种代码表述)
在bean标签上使用[p:属性名]或[c:属性名]或的方式直接注入属性,适用于一些较为简单的属性,并且支持ref引用类型。p标签就是property的缩写,c就是Constructor的缩写,因此使用p标签必须需要类具有Setter和无参构造方法,p命名空间的使用需要类具有有参构造方法。
<?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:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--DI之P命名空间注入-->
<bean id="money" class="com.ndkj.pojo.Money" p:moneyNum="11111"/>
<bean id="wife" class="com.ndkj.pojo.Wife" p:age="28" p:name="Taylor Swift"/>
<bean id="man" class="com.ndkj.pojo.Man" p:name="liu" p:age="20" p:money-ref="money" p:wife-ref="wife"/>
<!--DI之C命名空间注入-->
<bean id="wife" class="com.ndkj.pojo.Wife" c:name="taylor Swift" c:age="28"/>
<bean id="money" class="com.ndkj.pojo.Money" c:moneyNum="19999"/>
<bean id="man" class="com.ndkj.pojo.Man" c:age="19" c:name="liu" c:money-ref="money" c:wife-ref="wife"/>
</bean>
4.基于注解的依赖注入(补充):
@Autowired注解可以加在引用类型上和Setter方法上,先通过byType方式查找有无匹配的bean,没有则使用byName方式进行匹配,并且当有多个bean类型符合要求时,可以在@Autowired后可通过添加@Qualifier(value = “beanName”)注解设置指定的bean进行装配。注意在使用注解进行自动装配时,需要在配置文件中加入<context:annotation-config/>。
Class Man:
public class Man {
@Value("liu")
private String name;
@Value("20")
private int age;
@Autowired
private Money money;
@Autowired
private Wife wife;
public Man() {
}
public Man(String name, int age, Money money, Wife wife) {
this.name = name;
this.age = age;
this.money = money;
this.wife = wife;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Money getMoney() {
return money;
}
public void setMoney(Money money) {
this.money = money;
}
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
@Override
public String toString() {
return "Man{" +
"name='" + name + '\'' +
", age=" + age +
", money=" + money +
", wife=" + wife +
'}';
}
}
applicationContext.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:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<!--man-bean通过注解的方式实现自动装配-->
<bean id="money" class="com.ndkj.pojo.Money">
<property name="moneyNum" value="1000"/>
</bean>
<bean id="wife" class="com.ndkj.pojo.Wife">
<property name="age" value="20"/>
<property name="name" value="Taylor Swift"/>
</bean>
<bean id="man" class="com.ndkj.pojo.Man"/>
</bean>