1.什么是依赖注入?
依赖注入是一种设计模式,当程序运行依赖其他对象时,不需要自己new一个对象,而是通过容器使得所依赖的对象在外部创建,然后注入到当前类中,这样就降低了耦合度,提高了代码的可复用和可维护性
构造器注入
即通过类的构造器将依赖项注入到创建的实例中,在配置文件中使用constructor-arg标签将依赖注入给属性
2.set注入(重点)
本质是利用set方法实现属性的依赖注入,对于不同的数据类型,注入的方式也不同。以下是针对于String、int这种普通类型,其他类的类对象,数组类型,List类型,Set类型,Map类型,Properties类型使用set注入的方法,以Student类进行测试,其中Address也是自定义的类
//Student类
public class Student {
//普通类型String、int等类型注入
private String name;
private int age;
//其他类对象注入
private Address address;
//set类型注入
private Set<String> hobby;
//数组类型注入
private String[] email;
//List类型注入
private List<String> skill;
//Map类型注入
private Map<String,String> card;
//Properties类型注入
private Properties otherinfo;
//注入空值
private String 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 Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Set<String> getHobby() {
return hobby;
}
public void setHobby(Set<String> hobby) {
this.hobby = hobby;
}
public String[] getEmail() {
return email;
}
public void setEmail(String[] email) {
this.email = email;
}
public List<String> getSkill() {
return skill;
}
public void setSkill(List<String> skill) {
this.skill = skill;
}
public Map<String, String> getCard() {
return card;
}
public void setCard(Map<String, String> card) {
this.card = card;
}
public Properties getOtherinfo() {
return otherinfo;
}
public void setOtherinfo(Properties otherinfo) {
this.otherinfo = otherinfo;
}
public void setWife(String wife) {
this.wife = wife;
}
public String getWife() {
return wife;
}
}
//Address类
public class Address {
private String address;
public void setAddress(String address) {
this.address = address;
}
}
使用容器利用set方法注入
<!--创建Address对象供student使用-->
<bean name ="address" class="com.anzekun.Address">
<property name="address" value="earth"/>
</bean>
<bean name="student" class="com.anzekun.Student">
<!--普通类型注入-->
<property name="name" value="zhangsan"/>
<property name="age" value="15"/>
<!--其他类对象注入-->
<property name="address" ref="address"/>
<!--数组类型注入-->
<property name="email">
<array>
<value>123@qq.com</value>
<value>666@163.com</value>
</array>
</property>
<!--List类型注入-->
<property name="skill">
<list>
<value>精通java</value>
<value>精通C++</value>
</list>
</property>
<!--Set类型注入-->
<property name="hobby">
<set>
<value>打游戏</value>
<value>敲代码</value>
</set>
</property>
<!--Map类型注入-->
<property name="card">
<map>
<entry key="IDcard" value="123456"/>
<entry key="Studycard" value="2401001"/>
</map>
</property>
<!--Properties类型注入-->
<property name="otherinfo">
<props>
<prop key="身高">180cm</prop>
<prop key="体重">65kg</prop>
</props>
</property>
<!--注入空值,如果注入空串仅需将null标签换成属性value=""即可-->
<property name="wife">
<null/>
</property>
</bean>
3.拓展方式注入
还可以通过p命名空间和c命名空间注入,分别对应set注入和构造器注入
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
然后分别使用两种命名空间(注意在使用时要有一个无参构造和一个有参构造函数,分别用于p命名空间和c命名空间的注入):
<!--p命名空间-->
<bean name="st" class="com.anzekun.Student" p:name="zhangsan" p:age="10"/>
<!--c命名空间-->
<bean name="st1" class="com.anzekun.Student" c:name="lisi" c:age="20"/>
测试两种注入方式:
public static void main(String[] args) {
ApplicationContext context= new ClassPathXmlApplicationContext("beans1.xml");
Student student=(Student) context.getBean("st");
Student student1=context.getBean("st1",Student.class);
System.out.println(student.getName()+" "+student.getAge());
System.out.println(student1.getName()+" "+student1.getAge());
}
运行结果 :