一、DI(依赖注入)
依赖注入的前提就是要有IOC的环境,Spring管理这个类的时候将这个类的属性依赖注入。DI就是注入对象的属性,属性可以有基本属性也可以有对象属性。两种配置有微微区别。
二、依赖注入的配置
设定两个实体类学校类和学生类,学校类有名称和学生两个属性,学生类有姓名和年龄两个属性。
package spring.pojo;
/**
学生类
*/
public class Student {
private String name;
private Integer age;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
}
package spring.pojo;
/**
学校类
*/
public class School {
private String name;
private Student student;
public void setName(String name) {
this.name = name;
}
public void setStudent(Student student) {
this.student = student;
}
}
xml配置方式
实体类中必须包含set方法或者构造方法才可以进行依赖注入
以下介绍实体类中包含set方法
当对象属性为普通类型(即int,double,String,float......),使用value形式进行赋值,为对象类型的时候,使用ref方式记性赋值.。
<bean id="school" class="spring.pojo.School">
<property name="name" value="XX大学"/>
<property name="student" ref="student"/>
</bean>
<bean id="student" class="spring.pojo.Student">
<property name="name" value="张三"/>
<property name="age" value="21"/>
</bean>
此外,name属性的值应与实体类中的属性名对应。
构造方法的注入
<constructor-arg name="student" ref="student"/>
补充:如果属性名为复杂类型
list集合:
注入list集合
<property name="list">
<list>
<value>张三</value>
<value>张三三</value>
<value>张三四</value>
</list>
</property>
set集合:
注入set集合
<property name="set">
<set>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</set>
</property>
Map集合 :
<property name="map">
<map>
<entry key="aaa" value="111"/>
<entry key="bbb" value="222"/>
<entry key="ccc" value="333"/>
</map>
</property>
Spring中还提供了丰富的注入方式有
P标签方式(Spring2.5以后)以及Sp EL表达式方式(Spring3.0以后)
P名称空间注入
首先在在头文件补上以下这句话
xmlns:p="http://www.springframework.org/schema/p"
使用方式
普通属性 p:属性名=”值”
对象属性 p:属性名-ref=”id值”
<bean id="student" class="spring.pojo.Student" p:name="张三" p:age="18">
此外应注意: 使用P标签必须要有set方法
SpEL表达式(Spring3.0以后)
格式:#{SpEL}
<bean id="school" class="spring.pojo.School">
<property name="name" value="#{'XX大学'}"/>
<property name="student" value="#{student}"/>
</bean>
<bean id="student" class="spring.pojo.Student">
<property name="name" value="#{'李四'}"/>
<property name="age" value="#{'22'}"/>
</bean>
值得注意的是,使用SpEL表达式,引用对象类型,使用的也是value
注解方式注入
使用@Autowired、@Resource进行注入
其中@Autowired表示按照对象类型进行注入,@Resource表示按照对象名称进行注入。
以业务层与Dao层之间关系为例
开启包扫描
<context:component-scan base-package="spring"/>
在Dao层写上@Repository("userDao")注解
在Service层写上@Service("userService")注解
表示使用注解的方式进行控制反转
使用注解方式进行属性注入
首先介绍使用@Autowired进行注入
@Service("userService")
public class UserServiceImpl implements UserService{//按照名称类型进行注入
@Autowired
private UserDao userDao;
@Override
public void save() {
userDao.save();
System.out.println("UserServiceImpl中的save方法执行了......");
}@Override
public void update() {
System.out.println("UserServiceImpl中的update方法执行了......");
}@Override
public void delete() {
System.out.println("UserServiceImpl中的delete方法执行了......");
}@Override
public void find() {
System.out.println("UserServiceImpl中的find方法执行了......");
}}
在进行测试之前,介绍一下Spring整合junit4
在测试类之前加上
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
表示加载配置类,即不需要我们写
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext2.xml");
测试类
package spring.test;
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;import spring.service.UserService;
/**
* Spring4整合Test
* @author Cheng
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class SpringTest {
@Autowired
private UserService userService;//注入service层的类
@Test
public void test01(){
userService.save(); //调用save方法
}}
测试结果
UserDaoImpl中的save方法执行了......
UserServiceImpl中的save方法执行了......
所谓的按对象类型进行注入的意思是,在本次测试中,就是 根据UserService类型进行注入,看看项目中有没有UserService这个类型的类。不论@Service("userService")中名称是什么。如果使用@Resource按照对象名称进行注入,则必须与类上的名称保持一致
按照名称方式进行注入
@Resource(name="userService")
private UserService userService;//注入service层的类,按照名称方式进行注入
@Test
public void test01(){
userService.save(); //调用save方法
}
Resource(name="userService"),Resource中的name值必须与UserServiceImpl的名称保持一致,否则会报错。
补充:
(1)@Autowired+@Qualifier("userService")=Resource(name="userService")
使用@Qualifier可以强制按照名称方式进行注入
(2)如果配置文件中已经写了实体类的注入,此时只想用属性注解,则不用开启包扫描
直接使用“<context:annotation-config/>”