2019独角兽企业重金招聘Python工程师标准>>>

在Spring中,对象无需自己查找或创建与其所关联的其他对象。相反,容器负责把需要相互协作的对象引用赋予各个对象。

创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入的本质。

2.1 Spring配置的可选方案

Spring提供了三种主要的装配机制:

  • 在XML中进行显式配置;
  • 在Java中进行显式配置;
  • 隐式的bean发现机制和自动装配。

作者建议尽可能的使用自动装配的机制。显式配置越少越好,当必须要显式配置bean的时候(比如,有些源码不是由你来维护的,而当你需要为这些代码配置bean的时候),推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现是才应该使用XML。

2.2 自动化装配bean

Spring从两个角度实现自动化装配:

  • 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean;
  • 自动装配(autowiring):Spring自动满足bean之间的依赖。

2.2.1 创建可被发现的bean

在类上使用@Component注解,这个注解表明该类会作为组件类,并告知Spring要为这个类创建bean。

组件扫描默认是不启用的,还需要显式配置一下Spring,从而命令它去寻找带有@Component注解的类并为其创建bean。

@Configuation
@ComponentScan
public class CDPlayerConfig {
}

如果没有其他配置,@ComponentScan默认会扫描与配置类相同的包。

如果想使用XML来启用组件扫描,可以使用Spring context命名空间的context:component-scan元素。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:Context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframeword.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="soundsystem"/>
</beans>

测试组件扫描代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerText {@Autowiredprivate CompactDisc cd;@Testpublic void cdShouldNotBeNull() {assertNotNull(cd)}
}

CDPlayerTest使用了Spring的SpringJUnit4ClassRunner,以便在测试开始的时候自动创建Spring的应用上下文。注解@ContextConfiguration会告诉它需要在CDPlayerConfig中加载配置。

2.2.2 为组件扫描的bean命名

在组件扫描中如果没有明确的设置ID,Spring会根据类名为其指定一个ID。这个bean所给定的ID是首字母变为小写的类名。

如果想为这个bean设置不同的ID,需要将其作为值传递给@Component注解。

@Component("lonelyHeartsClub")
public class SgtPeppers implements CompactDisc {
}

另外一种bean命名方式使用Java依赖注入规范中提供的@Named注解:

@Named("lonelyHeartsClub")
public class SgtPeppers implements CompactDisc {
}

Spring支持将@Named作为@Component注解的替代方案。两者之间由一些细微的差异,但在大多数场景中可以互换。

本书的作者更喜欢@Component。

2.2.3 设置组件扫描的基础包

如果没有为@ComponentScan设置属性,按照默认规则,它会以配置类所在的包作为基础包来扫描逐渐。

如果想扫描不同的包,在@ComponentScan的value属性中指定包名即可。

@Configuraion
@ComponentScan("soundsystem")
public class CDPlayerConfig{
}

如果想更加清晰的表明所设置的是基础包,可以通过basePackages属性进行配置:

@Configuration
@ComponentScan(basePackages="soundsystem")
public class CDPlayerConfig{}

basePackages属性可以设置多个包,赋值一个数组即可:

@Configuration
@ComponentScan(basePackages={"soundsystem", "video"})
public class CDPlayerConfig { }

除了将包设置为简单的String类型外,@ComponentScan哈提供了另外一种方法,将其指定为包中所包含的类或接口:

@Configuration
@ComponentScan(basePackageClasses={CDPlayer.class, DVDPlayer.class})
public class CDPlayerConfig { }

2.2.4 通过为bean添加注解实现自动装配

可以在构造器、setter方法、任何方法上使用@Autowired注解,Spring会尝试满足方法参数上所声明的依赖。假如有且只有一个bean匹配依赖需求,那么这个bean将会被装配进来。

如果没有匹配的bean,那么在应用上下文创建的时候会抛出异常。可以将@Autowired的required属性设置为false,此时Spring会尝试自动装配,但是如果没有匹配的bean的话该属性将会为null。

如果有多个bean都满足依赖关系,Spring将会抛出异常。

@Autowired是Spring特有的注解。可以使用@Inject注解替代。

2.3 通过Java代码装配Bean

显式的装配方式有两种:Java和XML。

2.3.1 创建配置类

@Configuration注解表明这个类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。

2.3.2 声明简单bean

要在JavaConfig中声明bean,需要编写一个方法,这个方法会创建所需类型的实例,然后给这个方法添加@Bean注解。

@Bean注解会告诉Spring这个方法将返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了最终产生bean实例的逻辑。

默认情况下,bean的ID与方法名一致。如果想为其设置一个不同的名字,可以重命名该方法,也可以通过@Bean的name属性指定。

2.3.3 借助JavaConfig实现注入

在JavaConfig中装配bean的最简单方式就是引用创建bean的方法。在方法上添加了@Bean注解,Spring将会拦截所有对它的调用,并确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用。

通过调用方法引用bean的方式有点令人困惑。还有一种理解起来更简单的方式:

@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {return new CDPlayer(compactDisc);
}

cdPlaye()方法请求一个CompactDisc作为参数,当Spring调用cdPlayer()创建CDPlayer bean的时候,它会自动装配一个CompactDisc到配置方法之中。

通过这种方式引用其他的bean通常是最佳的选择,因为它不会要求将CompactDisc声明到同一个配置类之中。在这里甚至没有要求CompactDisc必须要在JavaConfig中声明,实际上它可以通过组件扫描功能自动发现或者通过XML来进行配置。可以将配置分散到多个配置类、XML文件以及自动扫面和装配bean之中。

2.4 通过XML装配Bean

2.4.1 创建XML配置规范

在XML配置中,要创建一个XML文件,并且要以<beans>元素为根。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframeword.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context"><!-- 配置详情 -->
</beans>

2.4.2 声明一个简单的<bean>

<bean>元素类似于JavaConfig中的@Bean注解。

如果没有给定ID,所以这个bean将会根据全限定类名来进行命名。例如“soundsystem.SgtPeppers#0“,其中“#0”是一个计数形式,用来区分相同类型的其他bean。

2.4.3 借助构造器注入初始化bean

构造器注入有两种基本的配置方案可供选择:

  • <constructon-arg>元素;
  • 使用Spring 3.0 所引入的c-命名空间。

构造器注入bean引用

<bean id="cdPlayer" class="soundsystem.CDPlayer"><constructor-arg ref="compactDisc"/>
</bean>

c-命名空间的schema:

xmlns:c="http://www.springframework.org/schema/c"
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:cd-ref="compactDisc" />

属性以c:开头,也就是命名空间的前缀。接下来是要装配的构造器参数名,在此之后是-ref,这是一个命名约定,告诉Spring正在装配的是一个bean应用。

可以使用参数在整个参数列表中的位置来替代参数名:

<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_0-ref="compactDisc" />

因为在XML中不允许数字作为属性的第一个字符,因此必须要添加一个下划线作为前缀。

如果只有一个参数,不用标示参数:

<bean id="cdPlayer" class="soundsystem.CDPlayer"c:_-ref="compactDisc" />

将字面量注入到构造器中

<bean id="compactDisc"class="soundsystem.BlankDisc"><constructor-arg value="sgt. Pepper" />
</bean>

依然使用<constructor-arg>元素进行注入,但是使用了value属性。

<bean id="compactDisc"class="soundsystem.BlankDisc"c:_title="sgt. Pepper"/>

使用c-命名空间装配字面量与装配引用的区别在于属性名中去掉了-ref后缀。

装配集合

<constructor-arg>可以将集合装配到构造器参数重,而c-命名空间不能。

可以使用<null/>元素将null传递给构造器。

可以使用<list>元素声明一个列表:

<constructor-arg><list><value>.....</value><value>......</value></list>
</constructor-arg>

<list>元素是<constructor-arg>的子元素,这表明一个包含值的列表将会传递到构造器中。其中<value>元素用来指定列表中的每个元素。

与之类似,可以使用<ref>元素代替<value>,实现bean引用列表的装配。

可以用相同的方式使用<set>元素。<set>和<list>元素的区别不大,无论在哪种情况下,<set>或<list>都可以用来装配List、Set甚至是数组。

2.4.4 设置属性

<property>元素为属性的setter方法所提供的功能与<constructor-arg>元素为构造器提供的功能是一样的。

Spring提供了p-命名空间作为<property>元素的替代方案。p-命名空间的schema:

xmlns:p="http://www.springframework.org/schema/p"

util-命名空间所提供的功能之一是util:list元素,它会创建一个列表的bean。

xmlns:util="http://www.springframework.org/schema/util"
<util:list id="trackList"><value>......</value><value>.....</value>
</util:list>

下表展示了Spring util-命名空间中的元素

元素 描述
util:constant 引用某个类型的public static域,并将其暴露为bean
util:list 创建一个java.util.List类型的bean,其中包含值或引用
util:map 创建一个java.util.Map类型的bean,其中包含值或引用
util:properties 创建一个java.util.Propertie类型的bean
util:property-path 引用一个bean的属性(或内嵌属性),并将其暴露为bean
util:set 创建一个java.util.Set类型的bean,其中包含值或引用

2.5 导入和混合配置

2.5.1 在JavaConfig中引用XML配置

使用@Import注解引用其他JavaConfig配置,使用@ImportResource注解引入XML配置。

@Configuration
@Import(CDPlayerConfig.class)
@ImportResource("classpath:cd-config.xml")
public class SoundSystemConfig {}

2.5.2 在XML配置中引用JavaConfig

在XML中可以使用<import>元素来引用其他XML配置。

将JavaConfig作为bean使用<bean>元素导入XML配置文件。

转载于:https://my.oschina.net/u/2453016/blog/1532349

《Spring实战》第四版读书笔记 第二章 装配Bean相关推荐

  1. Spring 实战 第4版 读书笔记

    第一部分:Spring的核心 1.第一章:Spring之旅 1.1.简化Java开发 创建Spring的主要目的是用来替代更加重量级的企业级Java技术,尤其是EJB.相对EJB来说,Spring提供 ...

  2. Java编程思想第四版读书笔记——第九章 接口

    这章介绍了适配器设计模式和策略设计模式. 第九章  接口 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 1.抽象类和抽象方法 public abstract void f(); 创 ...

  3. 《spring实战第四版》的读书笔记

    <spring实战第四版>的读书笔记 1 概述 <Spring实战第四版>描述了Spring4架构的设计,看完了以后,最大感觉是Spring的IOC与aop理念实在是太强大了, ...

  4. Think in Java第四版 读书笔记10 第16章 数组

    Think in Java第四版 读书笔记10 第16章 数组 数组和容器很像 但他们有一些差别 16.1 数组为什么特殊 数组与容器的区别主要在效率和存储类型 效率:数组是简单的线性序列 使得数组的 ...

  5. Think in Java第四版 读书笔记9第15章 泛型

    Think in Java第四版 读书笔记9第15章 泛型 泛型:适用于很多很多的类型 与其他语言相比 Java的泛型可能有许多局限 但是它还是有很多优点的. 本章介绍java泛型的局限和优势以及ja ...

  6. Spring实战(第四版)

    Spring实战(第四版) 链接:https://pan.baidu.com/s/1PhnJqOsQPz5hqe-zxkqPOg 提取码:eu15 复制这段内容后打开百度网盘手机App,操作更方便哦

  7. 《计算传播学导论》读书笔记——第二章文本分析简介

    <计算传播学导论>读书笔记--第二章文本分析简介 第一节 文本分析研究现状 常用文本挖掘技术 第二节 文本分析与传播学研究 (一)为什么文本挖掘技术逐渐受到传播学者的关注 (二)不同文本分 ...

  8. 第二章 装配Bean(Spring in action,3th)

                                         第二章 装配Bean 创建应用对象之间协作关系的行为通常被称为装配(wiring),是依赖注入的本质. XML方式声明Bean ...

  9. Spring实战(第4版)第2章 装配Bean

    文章目录 Spring实战(第4版)第2章 装配Bean 2.1 Spring配置的可选方案 2.2 自动化装配bean 2.2.1 创建可被发现的bean 2.2.2 为组件扫描的bean命名 2. ...

最新文章

  1. spring 下载地址
  2. 对付惰性必杀:(10+2)*5法
  3. 西安python工资怎么样-在西安为什么对Python编程需求这么大?工资这么高?
  4. 集训队脱单大法:这是一道只能由学姐我自己出数据的水题
  5. C语言:L1-034 点赞 (20分)(解题报告)
  6. HDFS源码解析:教你用HDFS客户端写数据
  7. js math保留两位小数
  8. Oracle_linux_lesson_p2
  9. LINQ 学习路程 -- 查询操作 ElementAt, ElementAtOrDefault
  10. excel文件修复工具_Excel文件打开后出错,部分内容丢失的修复技巧
  11. 关键时刻救一命:旧手机改造求生工具
  12. [高通MSM8953_64][Android10]新增并挂载custom分区
  13. Linux之iptables防火墙
  14. office安装双击setup后点击‘立即安装’无反应(闪退)
  15. python画猫hellokitty_如何用铅笔画HelloKitty? 原来是这样的
  16. 聚蓝bluetech便携式移动滤水壶 家用净水壶,值得拥有
  17. c语言搬山游戏,C语言实例:搬山游戏
  18. 计算机任务计划程序已损坏,win7系统弹出任务计划程序窗口显示该任务映像损坏或已篡改0x80041321错误代码的解决方法...
  19. 操作系统春招面试复习之:存储管理
  20. c语言保存mat图片的方法,把opencv Mat 按位存成bmp二值图像 (1bit 1pixel)

热门文章

  1. 20155327《Java程序设计》第二周学习总结
  2. 第一个简单的DEMO
  3. MIT python 第二课第四十分钟 取最小值的例子
  4. C++ 创建一个窗口
  5. SQL:RAND()返回随机数
  6. mysql join on 索引_连接查询,表关联查询join on,索引,触发器,视图
  7. Windows核心编程 第十九章 DLL基础
  8. 3764树上的异或值(自己研究的静态字典树)
  9. 【错误记录】Git 使用报错 ( git branch -a 仍能查询到已经删除的远程分支 )
  10. 【Binder 机制】AIDL 分析 ( 创建 AIDL 文件 | 创建 Parcelable 类 | AIDL 中使用 Parcelable 类 | 编译工程生成 AIDL 对应的Java源文件 )