一、概述
正如上一篇博客,程序并没有主动设置PersonService实例的name属性值,而是通过Spring配置文件配置的,这就是说,PersonService实例的属性值并不是程序主动设置的,而是由Spring容器来负责注入的。在依赖注入的模式下,创建被调用者的工作不再由调用者来完成,因此称为控制反转(IoC)。创建被调用者实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。
使用依赖注入,不仅可以为Bean注入普通的属性值,还可以注入其它Bean的引用。通过这种依赖注入,Java EE应用中的各种组件不需要以硬编码方式耦合在一起,甚至无须使用工厂模式。可见,依赖注入是目前最优秀的解耦方式,依赖注入让Spring的Bean以配置文件组织在一起,而不是以硬编码的方式耦合在一起。
二、依赖注入的注入方式
1. 设值注入:IoC容器使用属性的setter方法来注入被依赖的实例(常用)。
1.1 接口PersonService.java
package test;
public interface PersonService {
public void testPerson();
}
1.2 实现类PersonServiceImpl.java
package test;
public class PersonServiceImpl implements PersonService{
private PersonDao personDao;
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
public void testPerson() {
System.out.println("注入:" + personDao.testPerson());
}
}
1.3 接口PersonDao.java
package test;
public interface PersonDao {
public String testPerson();
}
1.4 实现类PersonDaoImpl.java
package test;
public class PersonDaoImpl implements PersonDao {
public String testPerson() {
return "依赖注入就是控制反转";
}
}
1.5 Spring配置文件bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- 将PersonService类部署成Spring容器中的Bean -->
<bean id="personService" class="test.PersonServiceImpl">
<property name="personDao" ref="personDao"/>
</bean>
<bean id="personDao" class="test.PersonDaoImpl"></bean>
</beans>
1.6 测试类TestSpring.java
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring {
public static void main(String[] args) {
// 创建Spring容器,一旦获得了该容器,就可通过该容器访问Spring容器中的Bean
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
System.out.println(ctx);
PersonServiceImpl p = ctx.getBean("personService" , PersonServiceImpl.class);
p.testPerson();
}
}
2. 构造注入:Ioc容器使用构造器来注入被依赖的实例。
2.1 实现类PersonServiceImpl.java
package test;
public class PersonServiceImpl implements PersonService{
private PersonDao personDao;
// 构造注入所需的带参数的构造器
public PersonServiceImpl(PersonDao personDao) {
this.personDao = personDao;
}
public void testPerson() {
System.out.println("注入:" + personDao.testPerson());
}
}
2.2 Spring配置文件bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- 将PersonService类部署成Spring容器中的Bean -->
<bean id="personService" class="test.PersonServiceImpl">
<!-- 使用构造注入 -->
<constructor-arg ref="personDao"/>
</bean>
<bean id="personDao" class="test.PersonDaoImpl"></bean>
</beans>
2.3 其它同上面的设值注入