【Spring实战】装配Bean

装配Bean

任何一个成功的应用都是由多个为了实现某一个业务目标而相互写作的组件构成的。创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入(DI)的本质。


主要内容:

  • 声明bean
  • 构造器注入和Setter方法注入
  • 装配bean
  • 控制bean的创建和销毁

1.Spring配置的可选方案

在 Spring 中提供了 3 种主要的装配机制:

  • 在 XML 文件中显式配置
  • 在 Java 的接口和类中实现配置
  • 隐式 Bean 的发现机制和自动装配原则

方案选择的原则

在现实的工作中,这 3 种方式都会被用到,并且在学习和工作之中常常混合使用,所以这里给出一些关于这 3 种优先级的建议:

1.最优先:通过隐式 Bean 的发现机制和自动装配的原则。
基于约定由于配置的原则,这种方式应该是最优先的

  • 好处:减少程序开发者的决定权,简单又不失灵活。

2.其次:Java 接口和类中配置实现配置
在没有办法使用自动装配原则的情况下应该优先考虑此类方法

  • 好处:避免 XML 配置的泛滥,也更为容易。
  • 典型场景:一个父类有多个子类,比如学生类有两个子类,一个男学生类和女学生类,通过 IoC 容器初始化一个学生类,容器将无法知道使用哪个子类去初始化,这个时候可以使用 Java 的注解配置去指定。

3.最后:XML 方式配置
在上述方法都无法使用的情况下,那么也只能选择 XML 配置的方式。

  • 好处:简单易懂(当然,特别是对于初学者)
  • 典型场景:当使用第三方类的时候,有些类并不是我们开发的,我们无法修改里面的代码,这个时候就通过 XML 的方式配置使用了。

2.自动化装配bean

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

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

2.1 创建可被发现的bean

@Component注解表明该类会作为组件类,并告知Spring要为这个类创建bean。默认,组件扫描是不启用的,因此,还需要显示配置一下spring,从而命令它去寻找带有@Component注解的类,并为其创建bean。

@ComponentScan注解启用了组件扫描。默认@ComponentScan会扫描与配置类相同的包。

另一种方法是通过使用Spring context命名空间的<context:component-scan>元素启用XML组件扫描。

2.2 为组件扫描的bean命名

在Spring上下文中,每个bean都有自己的ID。如果需要给某个类对应的bean一个特别的名字,则可以给@Component注解传入指定的参数。

另外一种为bean命名的方式是不适用@Component注解,而是使用Java依赖注入规范中所提供的@Named注解来为bean设置ID。

Spring支持将@Named作为@Component注解的替代方案。大多数情况下,两者是可以互相替换的。

2.3 设置组件扫描的基础包

默认情况下,@ComponentScan会以配置类所在的包作为基础包(base package)来扫描组件。为了指定不同的基础包,需要做的就是在@ComponentScan的value属性中指明包的名称。当设置多个基础包时,只需要将basePackages属性设置为要扫描包的一个数组即可。

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

也可以在包中创建一个用来进行扫描的空标记接口(marker interface)。通过标记接口的方式,依然可以保持对重构友好的接口的引用,可以避免引用任何实际的应用程序代码。

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

简单得说,自动装配的意思是让Spring从应用上下文中找到对应的bean的引用,并将它们注入到指定的bean。通过@Autowired注解可以完成自动装配

@Autowired注解不仅能够用在构造器上,还可以用在属性的Setter方法上。

实际上,Setter方法并没有什么特殊之处。@Autowired注解可以用在类的任何方法上。

只要对应类型的bean有且只有一个,则会自动装配到该属性上。如果没有找到对应的bean,应用会抛出对应的异常,如果想避免抛出这个异常,则需要设置@Autowired(required=false)。不过,在应用程序设计中,应该谨慎设置这个属性,因为这会使得你必须面对NullPointerException的问题。

如果存在多个同一类型的bean,则Spring会抛出异常,表示装配有歧义,解决办法有两个:(1)通过@Qualifier注解指定需要的bean的ID;(2)通过@Resource注解指定注入特定ID的bean;

@Autowired是Spring特有的注解。如果不愿意在代码中到处使用Spring特有的注解来完成自动装配任务的话,可以考虑将其替换为@Inject;@Inject注解来源于Java依赖注入规范,该规范同时还定义了@Named注解。在自动装配中,Spring同时支持@Inject和@Autowired。大多数情况下它们可以相互替换。

2.5 验证自动装配

使用断言判断它的行为与预期是否一致。例如StandardOutputStreamLog,这是来源于System Rules库的一个JUnit规则,该规则能够基于控制台的输出编写断言。

3.通过Java代码装配bean

在进行显式配置的时候,有两种可选方案:Java和XML。

JavaConfig文件不同于其他用于实现业务逻辑的Java代码,因此不能将JavaConfig文件业务逻辑代码混在一起。一般都会给JavaConfig文件新建一个单独的package。

3.1 创建配置类

创建JavaConfig类的关键在于为其添加@Configuration注解,表示这个类是配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。

3.2 声明简单的bean

要在JavaConfig中声明bean,需要编写一个方法,这个方法会创建所需类型的实例,然后给这个方法添加@Bean注解。@Bean注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了最终产生bean实例的逻辑。

默认情况下,bean的ID与带有@Bean注解的方法名是一样的。也可以通过name属性指定一个不同的名字。

3.3 借助JavaConfig实现注入

最简单的办法是将被引用的bean的生成函数传入到构造函数或者set函数中。

默认情况下,Spring中所有的bean都是单例模式。

可以将配置分散到多个配置类、XML文件以及自动扫描和装配bean中,只要功能完整健全即可。

带有@Bean注解的方法可以采用任何必要的Java功能来产生bean实例。

4.通过XML配置bean

这种是Spring中最原始的定义方式,在此不再详述。

5.导入和混合配置

通常,可能在一个Spring项目中同时使用自动配置和显式配置,而且,即使你更喜欢JavaConfig,也有很多场景下更适合使用XML配置。幸运的是,这些配置方法可以混合使用。

首先明确一点:对于自动配置,它从整个容器上下文中查找合适的bean,无论这个bean是来自JavaConfig还是XML配置

5.1 在JavaConfig中引用XML配置

  • 通过@Import注解导入其他的JavaConfig,并且支持同时导入多个配置文件;
  • 通过@ImportResource注解导入XML配置文件;

5.2 在XML配置中引用JavaConfig

  • 通过<import>标签引入其他的XML配置文件;
  • 通过<bean>标签导入Java配置文件到XML配置文件

通常的做法是:无论使用JavaConfig或者XML装配,都要创建一个root configuration,即模块化配置定义;并且在这个配置文件中开启自动扫描机制:<context:component-scan>或者@ComponentScan

6.总结

Spring 装配bean的三种方式:自动装配、基于Java文件装配和基于XML文件装配。

自动装配几乎不需要手动定义bean,建议优先选择自动装配;如果必须使用显式配置,则优先选择基于Java的配置,因为相比于XML文件,Java文件具备更多的能力、类型安全等特点;但是也有一种情况必须使用XML配置文件,即你需要使用某个名字空间(name space),该名字空间只在XML文件中可以使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

镰刀韭菜

看在我不断努力的份上,支持我吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值