Spring的依赖注入
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring的依赖注入相关的知识,希望对你有一定的参考价值。
Spring的依赖注入
1.理解依赖注入
(1)A对象需要调用B对象的方法,这种情形被称为依赖注入,即A对象依赖B对象;依赖注入(DI)也被成为控制反转(IoC);
(2)依赖注入的两种方式:
1)设值注入:IoC容器通过使用成员变量的setter方法来注入被依赖对象;
2)构造注入:IoC容器通过使用构造器来注入被依赖的对象;
2.设置注入
(1)Bean与Bean之间的依赖关系由Spring管理,Spring采用setter方法为目标Bean注入所需要的值,这种注入方式被称为设值注入;
(2)代码
public interface Person { //定义一个使用斧头的方法 public void useAxe(); }
public interface Axe { //Axe中定义一个chop()方法 public String chop(); }
public class Chinese implements Person{ private Axe axe; public void setAxe(Axe axe){ this.axe = axe; } //实现Person接口的useAxe()方法 @Override public void useAxe() { // TODO Auto-generated method stub //调用axe的chop方法 //表明Person对象依赖于axe对象 System.out.println(axe.chop()); } }
public class StoneAxe implements Axe{ @Override public String chop() { // TODO Auto-generated method stub return "石斧砍柴好慢"; } }
public class SteelAxe implements Axe{ @Override public String chop() { // TODO Auto-generated method stub return "钢斧砍柴真快"; } }
<?xml version="1.0" encoding="UTF-8"?> <!-- Spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 --> <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-4.0.xsd" > <!-- 配置chinese实例,其实现类是Chinese --> <bean id="chinese" class="test_2.Chinese"> <!-- 驱动调用chinese的setAxe方法,将容器中的StoneAxe作为参数传入 --> <property name="axe" ref="stoneAxe"/> <!-- <property name="axe" ref="steelAxe"/> --> </bean> <!-- 配置StoneAxe实例,其实现类是StoneAxe --> <bean id="stoneAxe" class="test_2.StoneAxe"></bean> <bean id="steelAxe" class="test_2.SteelAxe"></bean> </beans>
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanTest { public static void main(String[] args) { //创建Spring容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("test_2_bean.xml"); //获取chinese实例 Chinese chinese = ctx.getBean("chinese",Chinese.class); //调用chinese的useAxe()方法 chinese.useAxe(); } }
(3)使用Spring IoC的三个基本要点:
1)应用程序的各组件面向接口编程;
2)应用程序的各组件不再由程序主动创建,而是由Spring容器负责创建并初始化;
3)Spring采用配置文件或注解来管理Bean的实现类、依赖关系,Spring容器根据配置文件或注解,利用反射来 创建实例,并为之注入依赖关系。
3.构造注入
(1)利用构造器来设置依赖关系的方式被称为构造注入;
(2)本质:驱动Spring在底层以反射的方式执行带指定参数的构造器,当执行带参数的构造器时,就可以利用构造器参数对成员变量执行初始化;
(3)代码
public interface Axe { public String chop(); }
public interface Person { public void useAxe(); }
public class Chinese implements Person{ private Axe axe; //提供携带参数的构造器,参数是被依赖的Axe public Chinese(Axe axe){ this.axe = axe; } @Override public void useAxe() { // TODO Auto-generated method stub System.out.println(axe.chop()); } }
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanTest { public static void main(String[] args) { //创建容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("test_3_bean.xml"); //获取对象 Chinese c = ctx.getBean("chinese",Chinese.class); //调用方法 c.useAxe(); } }
<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-4.0.xsd" > <!-- 配置chinese实例,实现类是Chinese --> <bean id="chinese" class="test_3.Chinese"> <constructor-arg ref="stoneAxe"/> </bean> <!-- 配置stoneAxe实例,实现类是StoneAxe --> <bean id="stoneAxe" class="test_3.StoneAxe"/> </beans>
(4)配置<constructor-arg>元素,两个属性:
1)index
2)type
public class Student { private String name; private int age; private String sex; //构造器 public Student(){ } public Student(String name){ this.name = name; } public Student(String name,int age){ this(name); this.age = age; } public Student(String name,int age,String sex){ this(name,age); this.sex = sex; } //Student方法 public void sayHello(){ System.out.println("我的名字是"+this.name+",今年"+this.age+"岁,是个"+this.sex+"同学"); } }
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class StudentTest { public static void main(String[] args) { //创建容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("test_3_bean.xml"); //获取对象 Student st = ctx.getBean("student",Student.class); //执行方法 st.sayHello(); } }
<?xml version="1.0" encoding="UTF-8"?> <!-- Spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 --> <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-4.0.xsd" > <!-- 配置Student对象,其实现类是Student --> <!-- 构造注入 --> <bean id="student" class="test_3.Student"> <constructor-arg value="小明" index="0"/> <constructor-arg value="25" index="1" type="int"/> <constructor-arg value="男" index="2"/> <!-- <constructor-arg value="小明" /> <constructor-arg value="25" /> <constructor-arg value="男" /> --> </bean> </beans>
4.两种注入方式的对比
设值注入:通过无参构造器创建一个Bean,再使用setter方法注入依赖关系;
构造注入:直接调用有参数的构造器,当Bean实例被创建完成后,已经完成了依赖关系的注入;
以上是关于Spring的依赖注入的主要内容,如果未能解决你的问题,请参考以下文章
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段