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注入(代码片段

Android 片段和依赖注入

Android片段和依赖注入

Spring依赖注入的方式

spring依赖注入,和控制反转。用自己的话说是怎么说的。最好能够用代码来解释

Spring设置注入和构造注入的区别