依赖注入的配置

Spring的依赖注入分为基于构造函数的依赖注入基于setter方法的依赖注入

基于构造函数的依赖注入

  1. <!-- 通过构造器参数索引方式依赖注入 -->
  2. <bean id="byIndex" class="cn.javass.spring.chapter3.HelloImpl3">
  3. <constructor-arg index="0" value="Hello World!"/>
  4. <constructor-arg index="1" value="1"/>
  5. </bean>
  6. <!-- 通过构造器参数类型方式依赖注入 -->
  7. <bean id="byType" class="cn.javass.spring.chapter3.HelloImpl3">
  8. <constructor-arg type="java.lang.String" value="Hello World!"/>
  9. <constructor-arg type="int" value="2"/>
  10. </bean>
  11. <!-- 通过构造器参数名称方式依赖注入 -->
  12. <bean id="byName" class="cn.javass.spring.chapter3.HelloImpl3">
  13. <constructor-arg name="message" value="Hello World!"/>
  14. <constructor-arg name="index" value="3"/>
  15. </bean>
  16. <!-- 通过静态的工厂方法注入 -->
  17. <bean id="byName" class="cn.javass.spring.chapter3.HelloImpl3" factory-method="getBean">
  18. <constructor-arg name="message" value="Hello World!"/>
  19. <constructor-arg name="index" value="3"/>
  20. </bean>

基于setter方法的依赖注入

  1. <bean class="...HelloImpl4">
  2. <property name="message" value="Hello"/>
  3. <property name="index" value="1"/> //value中的值全部是字符串形式,如果转换出错会报异常
  4. </bean>
  5. <bean id="Hello2" class="com.csx.personal.web.services.HelloImpl2">
  6. <property name="msg" ref="message"/> //msg属性是一个类对象
  7. </bean>

循环依赖:创建Bean A需要Bean B,创建Bean B需要Bean C,创建Bean C需要Bean A 这样就形成了循环依赖。 Spring的解决方案:Spring创建Bean的时候会维护一个池,在创建A的时候会去池中查找A是否在池子中,假如发现就抛出循环依赖异常。

避免依赖注入时的循环依赖:可以使用setter方式注入,不要使用构造器形式的注入。

依赖配置常见列子

常量值注入配置

  1. <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  2. <!-- results in a setDriverClassName(String) call -->
  3. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  4. <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
  5. <property name="username" value="root"/>
  6. <property name="password" value="masterkaoli"/>
  7. </bean>

注入其他Bean

这边分别给出了一个引用当前容器和引用父容器中Bean的列子。

  1. <bean id="Hello2" class="com.csx.personal.web.services.HelloImpl2">
  2. <property name="msg"> //msg属性是一个类对象
  3. <ref bean="message"/> //引用同一个容器中id="message"的Bean
  4. </property>
  5. </bean>
  6. <!-- 引用父容器中的Bean -->
  7. <!-- in the parent context -->
  8. <bean id="accountService" class="com.something.SimpleAccountService">
  9. <!-- insert dependencies as required as here -->
  10. </bean>
  11. <!-- in the child (descendant) context -->
  12. <bean id="accountService" <!-- bean name is the same as the parent bean -->
  13. class="org.springframework.aop.framework.ProxyFactoryBean">
  14. <property name="target">
  15. <ref parent="accountService"/> <!-- notice how we refer to the parent bean -->
  16. </property>
  17. <!-- insert other configuration and dependencies as required here -->
  18. </bean>

注入内部Bean

内部bean:这种bean一般只让某个外部bean使用(和内部类相似),不让容器中的其他Bean使用。

  1. <bean id="outer" class="...">
  2. <property name="target">
  3. <!-- this is the inner bean -->
  4. <bean class="com.example.Person">
  5. <property name="name" value="Fiona Apple"/>
  6. <property name="age" value="25"/>
  7. </bean>
  8. </property>
  9. </bean>

集合的注入

集合类的注入建议使用util命名空间

  1. <util:map id="myMap" key-type="java.lang.String" value-type="java.lang.String">
  2. <entry key="key1" value="chen"/>
  3. <entry key="key2" value="zhao"/>
  4. </util:map>
  5. <util:list id="myList" value-type="java.lang.String">
  6. <value>chen</value>
  7. <value>zhao</value>
  8. </util:list>
  9. <util:set id="mySet" value-type="java.lang.String" scope="singleton">
  10. <value>chen</value>
  11. <value>zhao</value>
  12. </util:set>
  13. <util:properties id="myProp" location="classpath:xx.properties"/>

null值和空字符串的注入

  1. <bean class="...HelloImpl4">
  2. <property name="message"><null/></property> //null值
  3. <property name="index" value=""/> //空字符串
  4. </bean>

使用depends-on属性

depends-on属性用来指定bean的初始化顺序。这个属性只对scope是单列的bean生效

  1. <!--在实例化beanOne之前先实例化manager和accountDao这两个bean-->
  2. <bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
  3. <property name="manager" ref="manager" />
  4. </bean>
  5. <bean id="manager" class="ManagerBean" />
  6. <bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" />

懒加载

bean的定义中有一个lazy-init这个属性,用来设置单列bean在容器初始化后是否实例化这个bean。默认情况下容器是会实例化所有单例bean的,我们也建议这么做,因为这样能在容器初始化阶段就发现bean配置是否正确。如果一个Bean按照下面的设置,lazy-init被设置为true那么它不会被容器预初始化,只有在被使用的时候才被初始化。但是如果有一个单列类依赖了这个Bean,那么这个被设置成懒加载的Bean还是会被预初始化。

  1. <bean id="lazy" class="com.something.ExpensiveToCreateBean" lazy-init="true"/>

如果想设置全局的单例Bean都不要预先初始化,那么可以在xml中做如下设置:

  1. <beans default-lazy-init="true">
  2. <!-- no beans will be pre-instantiated... -->
  3. </beans>

Autowiring相关

当我们要往一个bean的某个属性里注入另外一个bean,我们会使用property +ref标签的形式。但是对于大型项目,假设有一个bean A被多个bean引用注入,如果A的id因为某种原因修改了,那么所有引用了A的bean的ref标签内容都得修改,这时候如果使用autowire="byType",那么引用了A的bean就完全不用修改了。

  1. <!--autowire的用法如下,对某个Bean配置autowire模式 -->
  2. <!--和给Bean的属性添加@AutoWired注解的效果一致-->
  3. <bean id="auto" class="example.autoBean" autowire="byType"/>

autowire的几种模式:

  • no模式:也是默认模式,这种模式下不会进行自动属性注入,需要我们自己通过value或者ref属性进行配置;
  • byName模式:通过属性的名称自动装配,Spring会在容器中查找名称与bean属性名称一致的bean,并自动注入到bean属性中。当然bean的属性需要有setter方法。例如:bean A有个属性master,master的setter方法就是setMaster,A设置了autowire="byName",那么Spring就会在容器中查找名为master的bean通过setMaster方法注入到A中;
  • byType:通过类型自动装配(注入)。Spring会在容器中查找类(Class)与bean属性类一致的bean,并自动注入到bean属性中,如果容器中包含多个这个类型的bean,Spring将抛出异常。如果没有找到这个类型的bean,那么注入动作将不会执行;
  • constructor:类似于byType,但是是通过构造函数的参数类型来匹配。假设bean A有构造函数A(B b, C c),那么Spring会在容器中查找类型为B和C的bean通过构造函数A(B b, C c)注入到A中。与byType一样,如果存在多个bean类型为B或者C,则会抛出异常。但时与byType不同的是,如果在容器中找不到匹配的类的bean,将抛出异常,因为Spring无法调用构造函数实例化这个bean;
  • default : 采用父级标签(即beans标签的default-autowire属性)的配置。

需要注意的是上面这5中方式注入都需要我们提供相应的setter方法,通过@Autowired的方式不需要提供相应的setter方法。

自动装配的缺点

  • 属性和构造函数参数设置中的显式依赖项会覆盖自动装配;

将Bean排除自动装配

如果按照下面的方式配置了Bean,那么这个Bean将不会作为自动装配的候选Bean。但是autowire-candidate自会对byType形式的自动注入生效,如果我们是通过byName的形式进行自动注入,那么还是能注入这个Bean。

  1. <bean id="auto" class="example.autoBean" autowire="byType" autowire-candidate="false"/>

如果我们只想让某些Bean作为自动装配的候选Bean,那么可以进行全局设置。如果做了下面的配置,那么只有id为bean1和bean2的Bean才会成为自动装配的候选Bean。同时default-autowire-candidates的值支持正则表达式形式。但是强烈建议不要配置这个选项的值,使用默认的配置就行。

  1. <beans default-autowire-candidates="bean1,bean2">
  2. </beans>

方法注入(单例依赖原型Bean)

我们在配置bean的时候首先要考虑这个bean是要配置成单例模式还是其他模式。 在我们的应用中,绝大多数类都是单例类。当单例类引用单例类,或者原型类引用原型类、单例类时,我们只要像普通的配置方式就行了。但是当一个单例类引用原型类时,就会出现问题。这种情况可以使用下面的方式进行注入。

  1. @Service
  2. @Scope("prototype")
  3. public class MyService1 {
  4. public void service() {
  5. System.out.println(this.toString() + ":id");
  6. }
  7. }
  8. @Service
  9. public abstract class MyService {
  10. private MyService1 service1;
  11. public void useService(){
  12. service1 = createService1();
  13. service1.service();
  14. }
  15. @Lookup("myService1")
  16. public abstract MyService1 createService1();
  17. }
  18. //也可以这样配置bean
  19. <bean id="serviceC" class="com.csx.demo.springdemo.service.ServiceC">
  20. <lookup-method bean="serviceD" name="createService"/>
  21. </bean>
  22. <bean id="serviceD" class="com.csx.demo.springdemo.service.ServiceD" scope="prototype"/>

Spring系列.依赖注入配置的更多相关文章

  1. SpringBoot系列: 理解 Spring 的依赖注入(一)

    ==============================Spring 的依赖注入==============================对于 Spring 程序, Spring 框架为我们提供 ...

  2. Spring.NET依赖注入框架学习--简介

    Spring.NET依赖注入框架学习--Spring.NET简介 概述 Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入. ...

  3. Bean 注解(Annotation)配置(3)- 依赖注入配置

    Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...

  4. Bean XML 配置(3)- 依赖注入配置

    Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...

  5. (spring-第3回【IoC基础篇】)spring的依赖注入-属性、构造函数、工厂方法等的注入(基于XML)

    Spring要把xml配置中bean的属性实例化为具体的bean,"依赖注入"是关卡.所谓的"依赖注入",就是把应用程序对bean的属性依赖都注入到spring ...

  6. Spring的依赖注入(DI)三种方式

    Spring依赖注入(DI)的三种方式,分别为: 1.  接口注入 2.  Setter方法注入 3.  构造方法注入 下面介绍一下这三种依赖注入在Spring中是怎么样实现的. 首先我们需要以下几个 ...

  7. 一步一步深入spring(3)--spring的依赖注入方式

    对于spring配置一个bean时,如果需要给该bean提供一些初始化参数,则需要通过依赖注入方式,所谓的依赖注入就是通过spring将bean所需要的一些参数传递到bean实例对象的过程,sprin ...

  8. spring的依赖注入是什么意思

    最近学习spring框架,对依赖注入有些模糊,遂上网翻阅资料,做了下列总结,原博客为CSDN 南夏的 spring的依赖注入是什么意思,侵删! Spring 能有效地组织J2EE应用各层的对象.不管是 ...

  9. Spring.NET依赖注入框架学习--简单对象注入

    Spring.NET依赖注入框架学习--简单对象注入 在前面的俩篇中讲解了依赖注入的概念以及Spring.NET框架的核心模块介绍,今天就要看看怎么来使用Spring.NET实现一个简单的对象注入 常 ...

随机推荐

  1. vue-cli 2.x 搭建项目

    一.vue-cli优势 1.成熟的vue项目架构设计 2.本地测试服务器 3.集成打包上线方案 二.系统要求 1.node.js 2. Git 3.node命令行终端 三.安装 1.安装vue-cli ...

  2. ABAP基础3:OPENSQL

    select result from source where condition group by fileds having condition order by fields into targ ...

  3. JQuery动态创建表单并提交

    // 捕捉链接的点击事件 $('#btn').click(function(){ // 取得要提交的参数 var my_val = $.trim($('#ipt').val()); // 取得要提交页 ...

  4. 基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁

    在开始本篇正文之前,解决一个 @疯疯过 指出的错误,再次感谢指正. 步骤如下: 删掉.Domain.Shared层中的项目引用,添加nuget依赖包Volo.Abp.Identity.Domain.S ...

  5. 王玉兰201771010128《面向对象与程序设计(Java)》第十一周学习总结

    一:理论知识部分: (1)集合:集合(Collection或称为容器)是一种包含多个元素并提供对所包含元素操作方法的类,其包含的元素可以由同一类型的对象组成,也可以由不同类型的对象组成. A:集合类的 ...

  6. POJ2377

    题目链接:http://poj.org/problem?id=2377 解题思路: Prim算法. Warning ! 注意考虑重边 ! 其实就是求最大生成树,没什么好说的,就上面那个坑. AC代码: ...

  7. 实验二、OpenCV图像滤波

    一.题目描述 对下面的图片进行滤波和边缘提取操作,请详细地记录每一步操作的步骤. 滤波操作可以用来过滤噪声,常见噪声有椒盐噪声和高斯噪声,椒盐噪声可以理解为斑点,随机出现在图像中的黑点或白点:高斯噪声 ...

  8. Python的大小整数池跟深浅copy

    一.小整数池 可变的数据类型:list dict set 可变: 就是里面的数据类型变了,但是指向的内存地址没变. 不可变的数据类型:str 数值类型 tuple 不可变:如果改变了里面的值,相应的只 ...

  9. linux高级管理第十四章--kvm虚拟化

    案例 安装kvm所需软件 验证 注:虚拟机要开启虚拟引擎 开启服务 环境准备 安装相关软件包 启动 创建网桥 重启,reboot 安装虚拟机 完成.

  10. 循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

    在前面随笔<循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理>中介绍了在Vue + Element整合框架中,实现了动态菜单和动态路由的处理,从而可以根据 ...