Spring实战(第4版)——读书笔记之Spring中的Bean装配

Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系,它提供了三种主要的装配机制:

1、通过XML配置文件装配Bean

    通常推荐使用组件扫描和自动装配实现Spring的自动化配置,但当你想要将第三方库中的组件装配到你的应用中时,你没有办法在它的类上添加@Component和@Autowired注解,也就不能使用自动化装配的方案了。
    这时,可以采用显式装配方案。有两种可选方案:Java和XML。
    本小节介绍如何通过XML配置文件显示装配Bean。

1.1、声明简单的Bean

在这里插入图片描述
    代码声明了一个简单的bean,通过id属性为bean指定名字,class属性为bean指定类型,要求使用全限定的类名。
    当Spring发现这个元素时,将会调用SgtPeppers的默认构造器来创建bean实例。

1.2、借助构造器注入初始化bean

    在Spring XML配置中,只有一种声明bean的方式;但XML中声明DI时,有多种可选的配置方案。具体到构造器注入,有两种基本的方案可供选择:

    (1)使用 < constructor-arg >元素 在这里插入图片描述
    当Spring遇到元素时,它会创建一个CDPlayer实例。元素告知Spring要将一个ID为compactDisc的bean引用传递到CDPlayer的构造器中。

    (2)使用Spring 3.0所引入的c-命名空间
在这里插入图片描述在这里插入图片描述
    c-命名空间是在Spring 3.0中引入的,它是在XML中更为简洁地描述构造器参数的方式。 使用前,要在XML的顶部声明其模式。
    上图使用了c-命名空间声明构造器参数,它作为元素的一个属性,下图描述了该属性名的组合:
在这里插入图片描述
    上图的c-命名空间直接引用了构造器参数的名称,会导致在编译代码时,将调试标志(debug symbol)保存在类代码中。如果在优化构建过程中,将调试标志移除掉,那么这种方式可能就无法正常执行了。
    替代的方案是我们使用参数在整个参数列表中的位置信息:
在这里插入图片描述
    对于只有一个构造器参数,可以不用标示参数信息:
在这里插入图片描述

1.3、将字面量注入到构造器中

1.3.1、要注入的类

在这里插入图片描述

1.3.2、XML之< constructor-arg >注入配置

在这里插入图片描述
    使用进行构造器参数注入。“ref”属性表示注入其他的bean的引用,“value”属性表示给定的值要以字面量的形式注入到构造器之中。

1.3.3、XML之 c 标签根据参数名称注入字面量

在这里插入图片描述

1.3.4、XML之 c 标签根据参数索引注入字面

在这里插入图片描述

1.4、装配集合

1.4.1、要装配的类

在这里插入图片描述

1.4.2、使用< list >标签进行集合的定义

在这里插入图片描述
    < list >元素是< constructor-arg >的子元素,表明一个包含多个值的列表将会传递到构造器中,元素用来指定列表中的每元个元素。
    与之类似,我们也可以使用< ref >元素替代< value >,实现bean引用列表的装配。例如:
在这里插入图片描述
    当构造器参数的类型是java.util.List时,应使用< list >元素。但也可按照同样的方式使用< set >。
    目前,使用c-命名空间的属性无法实现装配集合的功能。
    Spring为< constructor-arg >元素提供了c-命名空间作为替代方案,与之类似,Spring为< property >元素提供了p-命名空间作为替代方案。

1.5、使用p-命名空间进行引用属性装配

1.5.1、p-命名空间装配示例

    为了启用p-命名空间,须在XML文件中进行命名空间的声明:
在这里插入图片描述
    使用p-命名空间,装配compactDisc属性示例:
在这里插入图片描述

1.5.2、p-命名空间的属性组成

在这里插入图片描述

1.5.3、使用p-命名空间将字面量注入到属性中

       要装配的类:

在这里插入图片描述
       使用p-命名空间装配示例:
在这里插入图片描述
    与c-命名空间一样,装配bean引用与装配字面量的唯一区别在于是否带有“-ref”后缀。如果没有“-ref”后缀的话,所装配的就是字面量。
    注意,我们不能使用p-命名空间来装配集合,但我们可使用Spring util-命名空间中的一些功能来简化BlankDiscbean。

1.5.4、使用util-命名空间进行集合注入

    首先,需要在XML中声明util-命名空间及其模式:

在这里插入图片描述
    使用util-命名空间所提供的功能之一< util:list >元素,创建一个列表的bean:
在这里插入图片描述
    接下来,我们就可以像使用其他的bean那样,将列表bean注入到BlankDiscbean的tracks属性中:
在这里插入图片描述
    < util:list >只是util-命名空间中多个元素之一。util-命名空间提供的所有元素如下:
在这里插入图片描述

1.6、在JavaConfig中引入XML配置

1.6.1、在XML配置中配置Bean

在这里插入图片描述

1.6.2、使用@ImportResource注解引入XML配置

在这里插入图片描述
    使用@Import和@ImportResource来拆分JavaConfig类。

1.7、在XML配置中引入JavaConfig

在这里插入图片描述
    < import >元素用于导入其他的XML配置文件,< bean >元素能够导入JavaConfig类。

2、 通过Java代码装配Bean

    除了XML配置文件显示装配外,还可以通过JJavaConfig进行显式装配。但JavaConfig是更好的方案,因为它更为强大、类型安全并且对重构友好。
    因为JavaConfig是配置代码,这意味着它不应该包含任何业务逻辑,也不应侵入到业务逻辑代码中。所以通常会将JavaConfig放到单独的包中,使它与其他的应用程序逻辑分离开来,避免产生困惑。
    本小节介绍如何通过JavaConfig代码显示装配Bean。

2.1、声明简单的Bean

在这里插入图片描述
    在JavaConfig中声明bean,需要编写一个创建所需类型实例的方法,然后给这个方法添加@Bean注解。@Bean注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean。
    默认情况下,bean的ID与带有@Bean注解的方法名是一样的。本例中,通过name属性将该bean的ID指定为gtPeppers。

2.2、借助JavaConfig实现注入

2.2.1、引用创建Bean的方法

在这里插入图片描述
    cdPlayer()方法同样使用了@Bean注解,表明该方法会创建一个bean实例并将其注册到Spring应用上下文中。创建的bean ID为cdPlayer,与方法的名字相同。
    cdPlayer()方法中的构造器调用了创建SgtPeppers实例的方法,看似实例CompactDisc是通过调用sgtPeppers()得到的,但因为sgtPeppers()方法上添加了@Bean注解,Spring 会拦截所有对sgtPeppers()的调用,并确保返回的是由Spring本身调用sgtPeppers()方法创建的bean,(默认单例情况下)而不是每次都对其进行实际的调用。

2.2.2、引用Bean的方法创建的实例

在这里插入图片描述
    cdPlayer()方法请求CompactDisc作为参数。当Spring调用cdPlayer()创建CDPlayer实例时,Spring会自动装配一个CompactDisc到配置方法中。
    这种方式引用其他的bean通常是最佳选择。它不要求将CompactDisc声明到同一个配置类中。也没要求CompactDisc必须在JavaConfig中声明。
    强调:带有@Bean注解的方法可以采用任何必要的Java功能来产生bean实例。构造器和Setter方法只是@Bean方法的两个简单实例。

3、Bean的自动化装配

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

  1. 组件扫描(component scanning):Spring自动扫描应用上下文中创建的bean。

  2. 自动装配(autowiring):Spring自动满足bean之间的依赖。

Spring自动化装配Bean代码实现:

3.1、定义CD接口类CompactDisc

在这里插入图片描述

3.2、定义CompactDisc接口实现类SgtPeppers

在这里插入图片描述
    @Component注解表明该类为组件类,并告知Spring为这个类创建bean。默认情况下,spring会根据类名自动为Bean创建ID,也可以通过如下两种方式进行Bean实例ID的指定。
    方式一:@Component(“lonelyHeartClub”)
    方式二:使用Java依赖注入规范(Java Dependency Injection)中所提供的@Named注解来为bean设置ID。使用如下:

在这里插入图片描述
    Spring的组件扫描默认是不启用的,需要我们显式配置。

3.3、通过Java代码定义Spring组件扫描

在这里插入图片描述
    @Configuration注解标识此类是Spring配置类。
    @ComponentScan注解标识在Spring中启用组件扫描,默认情况下Spring会扫描与配置类相同的包及其子包下带有@Component注解的类。
    通过以下方式显示指定@ComponentScan注解扫描范围:
@ComponentScan(basePackages=“soundsystem”):指定单个包;
@ComponentScan(basePackages={“soundsystem”,“video”}):指定多个包;
@ComponentScan(basePackageClasses={CDPlayer.class,DVDPlayer.class}):数组中指定的类或接口所在的包将作为Spring扫描的基础包。

3.4、通过XML配置定义Spring组件扫描

在这里插入图片描述

3.5、创建测试类CDPlayerTest测试Bean的自动装配

在这里插入图片描述
  @RunWith(SpringJUnit4ClassRunner.class)用于自动创建Spring的应用上下文
  @ContextConfiguration指明Spring加载配置类的位置(或XML配置文件的位置)
  @Autowired注解用于注入Spring容器中创建的Bean对象

3.6、@Autowired注解使用说明

3.6.1、通过构造器自动装配

在这里插入图片描述

3.6.2、通过set方法自动装配

在这里插入图片描述    其实,对于标注了@Autowired注解的方法,Spring都会尝试满足方法参数上声明的依赖。如果有且只有一个bean匹配依赖,则此bean将会被装配进来;如果没有匹配的bean,Spring在应用上下文创建时会抛出一个异常。为避免异常的出现,可将@Autowired的required属性设置为false,如下图:
在这里插入图片描述
    将required属性设置为false时,Spring会尝试自动装配,若无匹配bean,Spring将会让这个bean处于未装配状态。
    但是,把required属性设置为false后,如果在你的代码中没有null检查,这个处于未装配状态的属性有可能会出现NullPointerException。
    对于有多个bean都能满足依赖关系的情况,Spring将会抛出一个异常,表明没有明确指定要选择哪个bean进行自动装配。
7. @Inject注解使用说明
    @Autowired是Spring特有的注解。如果你不愿意在代码中到处使用Spring的特定注解来完成自动装配任务的话,可以考虑将其替换为@Inject。如下图:
在这里插入图片描述
    @Inject注解源于Java依赖注入规范,该规范还为我们定义了@Named注解。在自动装配中,Spring同时支持@Inject和@Autowired。尽管@Inject和@Autowired之间有着一些细微的差别,但是在大多数场景下,它们都是可以互相替换的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值