spring的依赖注入方式

在过去,我们总是自己用new关键字新建一个对象。当两个类存在依赖关系时,我们必须考虑new的顺序,来保证正确性。这样一方面使得我们的设计很麻烦,另一方面使得两个类的依赖关系明显,增加了耦合度。为此,我们使用了Spring。Spring就相当于一个大容器,我们需要某个类时,就只需从里面获取,不用我们主动去new。两个类之间的依赖关系,Spring也会帮我们解决。这样可以降低耦合度,也使得设计更加方便。这就是Spring的控制反转,把新建对象的控制权交给Spring。
Spring的依赖注入是Spring的核心功能之一,通过依赖注入可以将类放入Spring容器中。Spring的依赖注入有四种方法,一种是设值注入,一种是构造注入,一种是实例工厂方式,一种是静态工厂方式。

  1. 设值注入
    主要是在Java类中给相应的属性设置set方法,然后在配置文件中使用标签设置其为属性。 若该属性是Bean,则可以使用ref属性来指定某一个bean。若是非bean,则可以使用value属性来初始化属性。
public class TestAction {


    private TestService testService;

    //set方法
    public void setTestService(TestService testService) {
        this.testService = testService;
    }

    @ResponseBody
    @RequestMapping(value="/testHello")
    public Map<String,Object> testHello(){
        testService.test();
        Map<String,Object> result=new HashMap<String,Object>();
        result.put("test", "testHello");
        return result;
    }
}
 <bean class="com.test.service.impl.TestServiceImpl" name="testService" id="testService" ></bean>
    <bean class="com.test.action.TestAction" id="testAction" name="testAction">
        <property name="testService" ref="testService"></property>
    </bean>
  1. 构造注入
    主要是在Java类中提供该类的构造函数,形参为你需要注入的属性。然后在配置文件中使用多个标签来配置构造函数的形参。若该形参是一个bean,则可以使用ref属性来配置。否则使用value属性。存在多个形参时,可以使用index属性来标记形参位置,也可以使用type属性标记形参类型。
public class TestAction {


    private TestService testService;
    private String string;

    public TestAction(TestService testService,String str) {
        // TODO 自动生成的构造函数存根
        this.testService=testService;
        this.string=str;
    }

    @ResponseBody
    @RequestMapping(value="/testHello")
    public Map<String,Object> testHello(){
        testService.test();
        Map<String,Object> result=new HashMap<String,Object>();
        result.put("test", "testHello");
        return result;
    }
}
<bean class="com.test.service.impl.TestServiceImpl" name="testService" id="testService" ></bean>
    <bean class="com.test.action.TestAction" id="testAction" name="testAction">
        <constructor-arg name="testService" ref="testService" index="0"></constructor-arg>
        <constructor-arg name="string" value="hello" index="1"></constructor-arg>
    </bean>
  1. 实例工厂注入
    实例工厂方式指的是写一个工厂类,里面有各种对象的新建方法,但都是费静态方法,所以需要实例一个工厂出来。在配置文件中,先写出该工厂的bean,然后再写出工厂每一个类的bean,而使用属性factory-bean说明是来自哪个工厂,用属性factory-method说明哪个方法。
public class ServiceFactory {

    public TestServiceImpl geTestServiceImpl() {
        return new TestServiceImpl();
    }
}
public class TestAction {

    private TestServiceImpl testServiceImpl;

    public void setTestServiceImpl(TestServiceImpl testServiceImpl) {
        this.testServiceImpl = testServiceImpl;
    }

    @ResponseBody
    @RequestMapping(value="/testHello")
    public Map<String,Object> testHello(){
        testServiceImpl.test();
        Map<String,Object> result=new HashMap<String,Object>();
        result.put("test", "testHello");
        return result;
    }
}
<bean class="com.test.action.ServiceFactory" name="serviceFactory"></bean>
     <bean name="testServiceImpl" factory-bean="serviceFactory" factory-method="geTestServiceImpl"></bean>
    <bean class="com.test.action.TestAction" id="testAction" name="testAction">
        <property name="testServiceImpl" ref="testServiceImpl"></property>
    </bean>
  1. 静态工厂方式
    静态工厂与实例工厂类似,但里面的方法都是静态的,这样不用实例一个工厂出来。在配置文件中,不用写出工厂的bean。对于工厂的每一个类的bean,用class属性说明来源的工厂,用factory-method来说明哪个方法。
<bean name="testServiceImpl" class="com.test.action.ServiceFactory" factory-method="geTestServiceImpl"></bean>
    <bean class="com.test.action.TestAction" id="testAction" name="testAction">
        <property name="testServiceImpl" ref="testServiceImpl"></property>
    </bean>

一般来说,设值注入和构造注入使用比较多。当这种都存在的时候,先设值注入再构造注入。其两种区别是:设值注入更加简单,易懂,同时使得依赖关系更加直观,自然。对于多参数的构造函数时,构造方式显得累赘,笨重。但构造注入方式可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。设值注入是先构造出本身,再初始化其依赖属性。而构造注入反过来。

  1. 获取bean的方式
    Spring容器最基本的接口是BeanFactory。其负责配置,创建,管理Bean。它有一个子接口:ApplicationContext,称为Spring上下文。BeanFactory常用的实现类是DefaultListableBeanFactory,ApplicationContext常用实现类是:FileSystemXmlApplicationContext,(从文件系统中加载xml配置文件来创建bean),ClassPathXmlApplicationContext(从类加载路径中加载xml配置文件创建bean), AnnotationConfigWebApplicationContext(通过加载Java配置类【使用了@Configuration】来创建bean)。

  2. BeanFactory与ApplicationContext的区别:
    使用BeanFactory来加载时,不会预初始化容器的bean,而ApplicationContext会预初始化。所以,系统在创建ApplicationContext有较大的开销,一旦初始化结束,获取bean就有很好的性能。(也可以使用lazy-init属性指定延时加载)。ApplicationContext还能提供国际化支持,资源访问,事件机制,同时加载多个xml文件,以声明式方式启动并创建Spring容器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值