Spring in Action第四版第二章总结

前言

在本书的第一章中,我对spring架构有了一个大概的了解,包括它的一些特点和一些运作的机制。但是毕竟初学,理解上难免有些片面。所以趁着劲儿头,很快读完了第二章。

第二章主要介绍spring依赖注入的实现方法,给它取一个高大上的名字——Bean的装配。在上一章中我就曾对Bean这个东西产生过疑问,What’s Bean ?当时也是频繁的拜访度娘,最终得出了一个“Bean是类的代言人或者是一个组件”的解释。说实话,对于这个解释我还是云里雾里。但是学完这章之后,我确实对Bean有了新的理解和认识。

Ok,总结开始。。。。。。
Spring总共为我们提供了三种装配Bean的方式,分别是XML文件显示装配,Java配置类中显示装配以及自动装配。以上是从技术问世的前后顺序来罗列的,也就是说XML文件装配是最古老的方式,自动装配是新的技术。从某种意义上讲,我们的技术只会越来越先进,所以书中推荐我们在实际应用中,首先考虑自动装配,然后是Java配置类,最后才是XML。下面我们按照推荐的顺序进行介绍。

自动化装配Bean

自动化的装配当然是让容器为我们自动装配好Bean,当然了,并没有绝对的自动。我们这里的自动其实是相对于后边两种显示装配的方式而言的。Spring实现自动化的装配主要是依靠两个步骤:组件扫描和自动装配。组件扫描主要是让容器发现整个应用中所需要的所有Bean,自动装配主要是实现Bean之间的依赖。两者组合在一起就能发挥出巨大的威力。

实现组件扫描

在这一部分我们需要完成两个任务,一个是让我们的Bean能够被发现,另一个是找一个类似于扫描仪的东西来找出所有的Bean。

其一,我们在每一个需要被注册为Bean的Java类上加上一个@Component注解,这样就相当于告诉了容器这个类是组件类,并且需要被创建为Bean。示例代码如下:

package org.action.chapter2.soundsystem;

import org.springframework.stereotype.Component;

@Component
public class SgtPeppers implements CompactDisc {

	private String title = "Sgt, Pepper's Lonely Hearts Club Band";
	private String artist = "The Beatles";
	
	public void play() {
		System.out.println("Playing "+title+" by "+artist);
	}

}

当然我们这里的SgtPeppers类(据说是摇滚乐历史上最伟大的一张专辑,咱也不懂)实现了一个CD接口,这样的设计大大体现了我们Spring低耦合度的理念。

其二,我们需要一个扫描器,这个扫描器是通过Java显示配置或者XML显示配置来实现的。通过一个@ComponentScan注释实现组件的扫描,代码如下:

package org.action.chapter2.soundsystem;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration   //表明这是一个配置类
@ComponentScan   //组件扫描
public class CDPlayerConfig {
}

或者XML文件:

<?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"
  xmlns:c="http://www.springframework.org/schema/c"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

  <context:component-scan base-package="soundsystem" />  //组建扫描,并定义基础包

</beans>

这样组件扫描就能实现了。之后再说一下通过组件扫描我们还能做什么。两件事儿,其一为Bean命名;其二,规定组件扫描的基础包。

其一,我们可以在@Component注解中为命名:(若不命名,默认为类名首字母小写)

@Component("lonelyHeartsClub")

其二,基础包就是扫描器在扫描的时候从哪开始,就是规定了扫描的范围。基础包以及其下的所有子包。我们可以在@ComponentScan注解中添加基础包:

@ComponentScan("soundsystem")

或者

@ComponentScan(basePackages = "soundsystem")   //一个
@ComponentScan(basePackages = {"soundsystem", "video"})   //多个

还有一种方式,通过一个类定位到其所在的包:

@ComponentScan(basePackageClasses = {CDPlayer.class,DVDPlayer.class})
实现自动装配

组件扫描实现了一些单个Java创建为Bean,但这前提是它们并没有对别的类有所依赖。如果一个类对别的类有所依赖,也就是它的属性中包含其他的类,那该怎么将它创建为Bean呢?这就是自动装配要解决的问题。我们通过在相应的类的构造函数或者setter方法上添加@Autowired或者@Inject 注解来实现,代码如下:

package org.action.chapter2.soundsystem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CDPlayer implements MediaPlayer {

	private CompactDisc cd;
	
	@Autowired
	public CDPlayer(CompactDisc cd) {
		this.cd = cd;
	}

	public void play() {
		cd.play();
	}

}

这样的话,我们的容器就会找到该组件需要的Bean并将其传入该组件,从而创建成Bean。

Java代码装配Bean

这里我们就是需要通过一个Java的配置类来完成工作。这个类在自动装配中用到过,不过在这里又与其有所区别。首先我们不再需要@ComponentScan这个组件扫描的注解了,我们需要手动的进行配置,但是仍然需要@Configuration注解来表明是个配置类。之后需要分别实现声明Bean和实现依赖注入。

声明Bean

想要声明一个Bean我们需要在配置类中编写相应的方法,这个方法用来创建相应的实例,并添加@Bean注解。代码如下:

@Bean
	public CompactDisc sgtPeppers() {
		return new sgtPeppers();
	}

可为Bean命名:(若不命名,默认为方法名)

@Bean(name="lonelyHeartsClubBand")

那么在这里需要说明的一点是,通过Java配置类来声明Bean为我们提供了很大的自由空间。也就是我们的方法只要是返回一个所需要的Java类就可以了,那么在方法中添加复杂的逻辑是完全可以的。比如说书中给出了一个通过随机数生成随机的CD唱片的例子。因为配置类本身就是用Java语言来编写的,所以这种配置方式是最为全面,也是最为安全可靠的,它的实现方式仅仅受到Java语言的限制。

实现依赖注入

从本质上来说,依赖注入其实也是为了实例化相应的类,只不过是这些类的属性中包含了其他的类。在Java配置类中还是通过返回相应类的方法来实现依赖注入,通过用@Bean注解修饰。我可以在方法中调用实例化其他类的方法,或者直接将该类作为参数传入方法中,并在方法中调用其构造函数或者setter方法。代码如下:

@Bean
	public CDPlayer cdPlayer() {
		return new CDPlayer(sgtPeppers());
	}
@Bean
	public CDPlayer cdPlayer(CompactDisc compactDisc) {
		return new CDPlayer(compactDisc);
	} 
XML文件装配Bean

XML文件是一种古老的方式,书中指出我们学习这种方式可能更多的是为了今后在读一些前人的代码时容易理解,或者调试一些古老的项目的代码的时候能够容易一些。这种方法确实很笨重,前两种方法仅仅用了9页和4页的篇幅来介绍,而单纯这种方法就用了14页。这里边元素比较多,可能会需要一定的记忆,这就不太好了,毕竟程序员能懒则懒(微笑)。这里给出Spring in Action官方电子书的网址供查阅和参考

!!!注意Bean的命名问题

前边提到如果我们不为Bean命名的话,那么它们的命字默认为相应的类名首字母小写或者相应的方法名。这样的话我们在之后的依赖注入的时候,如果需要用到Bean的名字,比如说XML的方式中,可能会因为某个类或者方法名被改变而造成没有这样的Bean的错误。可以通过为每个Bean添加名字来避免这种情况的发生。

方式的组合使用

这里自动装配不会关心Bean来自于哪里,不管是哪种方式声明的,所以我们不需要担心自动装配。在这里着重介绍Java配置类和XML文件自己和自己以及互相之间的导入。

Java配置类中导入Java配置类
@Import(CDConfig.class)
Java配置类中导入XML配置文件
@ImportResource("classpath:cd-config.xml")
XML中导入XML文件
<import resource="cd-config.xml"/>
XML中导入Java配置类

这个我们就不能通过导入元素来进行导入了,因为XML只能导入XML资源,并没有一个元素可以导入Java配置类。但是Spring很巧妙的用了一种方法。我们Java和其他的类一样就是普通的类,那么我们就可以将配置类声明成Bean:

<bean class="soundsystem.CDConfig"/>

总结

以上就是Spring装配Bean的三种基本方式了。我们知道Spring最重要的技术就是依赖注入和面向切面,在第一章中我们也说过,要想实现依赖注入其实就是要在POJO的基础上,为容器绘制一张族谱,从而让容器来操控这一切。通过这一章的学习我对Bean有了全新的认识,其实和之前Java开发中的将一个类实例化一样,不过之前是我们自己编写相应的代码在类与类之间实现类的实例化。而在这里我们是要告诉容器,让他来帮助我们统一实例化和管理这些对象。既然这样,那么我们肯定就要告诉容器哪些类需要实例化(组件扫描),同时要告诉容器某些类实例化的时候都依赖于哪些类(自动装配、依赖注入)。那我们如何告诉容器呢,就是通过我们这一章的三种方法。与其说是方法,不如称之为语言,程序员与容器交流的语言。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值