Spring依赖注入概念

来源:互联网 发布:淘宝假发店铺推荐知乎 编辑:程序博客网 时间:2024/06/08 06:00

依赖注入的情况如下:
有两个组件如A和B,A依赖于B,即假设A和B 都是类,且A有一个方法使用到了B,那么如果想要使用B,A必须先要获得组件B的实例引用。这时候如果B是一个接口,虽然我们可以通过该接口的任一实现类来获取组件B的实例引用,但是这样就会使A的可重用性大大降低,无法再采用B的其他实现。
为此我们可以使用依赖注入的方式来解决这个问题,有两种办法:
1.编写特定的setter方法
2.采用构造器注入的方式编写特定的构建方法
示例;

// use appoint setter methodpublic class A {    private B b ;    private setB(B b) {        this.b = b ;    }    public void test() {        //we don't need instant B        // B b = ...        b.method();    }}
//use appoint construction methodpublic class A {    private B b ;    private A(B b) {        this.b = b ;    }    public void test() {        //we don't need instant B        //B b = ...        b.method();    }}

在Spring中,从1.0版本开始,他就同时支持setter和构造器方式的依赖注入,使用Spring,程序几乎将所有重要的对象的创建工作都交给了Spring,并且配置如何注入依赖。此外,还需要创建一个ApplicationContext,代表一个Spring控制反转容器,org.springframework.context.ApplicationContext接口有多个实现,其中Spring中最常用的两个为:ClassPathXmlApplicationContext和FileSystemXmlApplicationContext。这两个实现都需要至少一个包含beans信息的xml文件,也就是Spring的配置文件,ClassPathXmlApplicationContext类尝试在类加载路径中加载配置文件,FileSystemXmlApplicationContext类从文件系统中加载配置文件。
示例从类加载路径中加载config1.xml和config2.xml的ApplicationContext创建的实现代码:

ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"config1.xml","config2.xml"});//getBean()方法会查询id为product且类型为Product的bean对象Product product = context.getBean("product",Product.class);

在XML文件中配置Spring,从1.0版本开始就支持基于XML的配置,从2.5版本开始就增加了通过注解的配置的支持。配置文件的根元素通常为:beans,配置文件的头部内容这里就省略不写了。

Spring配置文件支持模块化配置,ApplicationContext的实现类也支持读取多个配置文件,我们可以通过一份主配置文件,将该文件导入到其他配置文件。

<?xml version = "1.0" encoding = "utf-8" ?><beans ...>    <import resources = "config1.xml"/>    <import resources = "confg2.xml"/>    ...</beans>

下面我们通过构造器来创建一个bean实例:

//编写配置文件spring-config.xml,在配置文件中定义一个名为product的bean<?xml version="1.0" encoding="utf-8"?><beans ...>    <bean name="product" class="com.springBean.Product"/></beans>//创建该Bean实例ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring-config.xml"});Product product1 = context.getBean("product",Product.class);

我们也可以通过工厂方法来创建一个bean实例,bean标签的factory-method属性指定用来实例化类的方法

<bean id="calendar" class="java.uril.Calendar" factory-method="getInstance"/>

有时候我们还希望一些类在被销毁之前执行某个方法,这时候我们可以使用bean标签的destroy-method属性来指定被销毁之前需要执行的方法名

上面所用到的使用Spring来创建bean实例都是在无参数的情况下创建的,Spring还支持通过带参数的构造器来初始化类,例如下面这个类中包含了三个属性,这时候我们创建该实例如果需要指定该实例的三个属性的值,我们就需要使用他的带参数的构造器来初始化类:

public class Product {    private String name ;    private String description ;    private float price ;    //omit setter and getter method     public Product() {    }    public Product(String name,String description,float price) {        this.name = name ;        this.description = description ;        this.price = price ;    }//在配置文件中定义该类的bean并传递参数的值的方式<bean name="product" class="com.springBean.Product">    <constructor-arg name="name" value="oil"/>    <constructor-arg name="description" value="life neccessary"/>    <constructor-arg name="price" value="9.99"/></bean>//也可以使用指数方式来传递参数<bean name="product" class="com.springBean.Product">    <constructor-arg index="0" value="oil"/>    <constructot-arg index="1" value="life neccessary"/>    <constructor-arg index="2" value="9.99'/></bean>

下面通过一个示例来展示Spring的依赖注入

//之前所说的B类,Addresspublic  class Address {    private String city ;    private String state ;    //omit setter and getter method    public Address(String city,String state) {        this.city = city ;        this.state = state ;    }//之前所说的A类,Employeepublic class Employee {    private String firstName;    private String lastName ;    private Address homeAddress ;    //omit setter and getter method    public Employee(String firstName,String lastName,Address homeAddress) {        this.firstName = firstName ;        this.lastName = lastName ;        this.homeAddress = homeAddress ;    }}//Employee依赖于Address注入,通过如下配置保证每个Employee实例都能包含Address实例<bean name="simpleAddress" class="com.springBean.Address">    <constructor-arg name="city" value="hunan"/>    <constructor-arg name="state" value="China"/></bean><bean name="employee1" class="com.springBean.Employee">    <property name="firstName" value="hengyang"/>    <property name="lastName" value="zhuzhou"/>    <property name="homeAddress" ref="simpleAddress"/></bean>//也可以通过构造器注入<bean name="employee2" class="com.springBean.Employee">    <constructor-arg name="firstName" value="hengyang"/>    <constructor-arg name="lastName" value="zhuzhou"/>    <constructor-arg name="homeAddress" ref="simpleAddress"/></bean>
0 0