Spring实战——无需一行xml配置实现自动化注入
已经想不起来上一次买技术相关的书是什么时候了,一直以来都习惯性的下载一份电子档看看。显然,如果不是基于强烈的需求或强大的动力鞭策下,大部分的书籍也都只是蜻蜓点水,浮光掠影。
就像有位同事说的一样,有些书没有真真切切的经历过,你去看,看了就是看了,只是没有留下多少印象。我回头仔细想了想,大概就是这样,好比你去看设计模式相关的书籍,了解到了适配器模式,但是还是不够深刻。比如说某天你去面试的时候别人会问你,"你了解过适配器模式么,你有过这个模式的开发经历么,你能否画出你使用适配器模式的UML图..." 如果当时看书的时候没有动手,你可能会先“让懵逼飞一会儿”, 然后一直懵逼-_-! 设想面试之后,你便迫不及待的回去重新翻了一遍什么是设配器模式,有哪几种适配器模式,连抄代写的画出了自己的UML图。这时候书上的适配器模式就成了你自己的适配器模式。
上面大概说了下电子档书籍可能会让你带来看书上面的懈怠,毕竟大部分电子档书籍都是唾手可得的,近乎免费(偶尔有些网站需要积分来兑现),而人却又这样的一个认知惯性,就是这样越容易得到的往往不太会珍惜,所以读书往往不能物尽其用。当然了,电子档数据有其先天的优势,比如便宜,比如方便易携带,比如你猛地一天想起一个知识点,就可以全局搜索一把来精准定位等等。说到这些优点也真是纸质书籍相形见绌的,一本800页的大部头书籍让你装在包里用来乘坐地铁时打发时间,我想能坚持下来的体力应该都还不错。对于动辄就是好几十甚至好几百的书籍,再查看下这个月的消费账单,想想还是先填饱自己的肚子吧。或者哪天你突然想起来需要找到一句在书中出现的至理名言,好吧,准备瓶眼药水可劲的找吧,但愿你当时做了笔记或者折了书角。但是纸质书籍也有他的好,首先不上眼,其次可以做笔记,当你真真切切的翻过某一页的时候,你可能会谨慎的问自己,过去的一夜我真的懂了么。
说了这么多闲话,只是为了引出——我买了一本《Spring 实战(第四版)》
理由很简单:一是学习需要;二是支持下知识产权。
看了第一章和第二章,发现其实在Spring 4版本中有很多的新特性了,但是网上流传的还是传统的用法,所以决定有必要梳理分享下。
环境介绍
Intellij Idea:14.0.2
Gradle:2.7
JDK:1.8.0_60
Spring-framework: 4.0.7.RELEASE
这篇开始主要讲的是依赖注入,值得一提的是,从作者的文字看来是极力推崇自动化装配方案的,而不是稍显臃肿的基于xml配置。
环境搭建
Gradle
Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。
这个东东以前从来没有接触过,但是因为Spring提供的代码是基于这个构建工具来解决依赖管理的,我暂且认为它和maven的作用等同,某种程度上来说,比maven来的要简洁(源于maven是基于xml方式配置依赖的),具体看后面就知道是不是名副其实的简洁style了。真的看下来,其实也没有什么特别的地方,起码示例项目跑起来并不那么复杂。
首先来一睹Spring实战的某个项目中用于自动化构建的文件
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea' jar {
baseName = 'stereo-autoconfig'
version = '0.0.1-SNAPSHOT'
} repositories {
mavenLocal()
mavenCentral()
} dependencies {
compile "org.springframework:spring-context:${springVersion}" testCompile "org.springframework:spring-test:${springVersion}"
testCompile "com.github.stefanbirkner:system-rules:${systemRulesVersion}"
} task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
这里的repositories实际上除了添加maven仓库以外,还支持Ivy和Ant仓库
dependencies中就是你们熟悉的maven配置,乍一看,着实简洁了太多,不用在写GroupId,ArtifactId,Version等等。这个简洁范儿,我喜欢。
还有就是gradleVersion,就是Gradle版本。
备注:本来准备自己机子上装个Gradle,但是发现机子上不知什么时候已经装好了,好吧,就不再介绍安装了,网上一查资料很多跟配置Maven差不多。
项目导入
1. 打开Intellij Idea,选择File->Import Project
2.选择导入的项目
3. 选择Gradle项目类型
4. 进入下一步选择Gradle点击finish
5. 完成build compile等步骤后,完成项目导入
6. 项目目录结构
备注:在构建项目的过程中遇到类似这样的错误
19:25:19: Executing external task 'build'...
:compileJava FAILURE: Build failed with an exception. * What went wrong:
Could not resolve all dependencies for configuration ':compile'.
> Could not resolve org.springframework:spring-context:4.0.7.RELEASE.
Required by:
:stereo-mixedconfig:unspecified
> Could not HEAD 'http://maven.oschina.net/content/groups/public/org/springframework/spring-context/4.0.7.RELEASE/spring-context-4.0.7.RELEASE.pom'.
> Connection to http://maven.oschina.net refused * Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. BUILD FAILED Total time: 24.733 secs
Connection timed out: connect
19:25:45: External task execution finished 'build'.
主要就是中央仓库慢或者ping不通,无法下载依赖的jar包,最后通过更改中央仓库的地址为
repositories {
mavenLocal()
maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
}
Spring装配Bean的方式有三种:
在XML中进行显示配置;
在Java中进行显示配置;
隐式的bean发现机制和自动装配。
书中作者推荐的顺序依次是隐式的bean发现机制和自动装配->在Java中进行显示配置->在XML中进行显示配置,理由也很简单,尽可能的减少显示配置,好比在XML文件中声明这种。这里首先来介绍这种自动化装配方式(基于XML的方式已经在《学习Spring——依赖注入》中介绍过了)。
Spring实现自动化化装配需要从以下两个方面:
组件扫描(component scanning): Spring会自动发现应用上下文中所创建的bean。
自动装配(autowiring):Spring自动满足bean之间的依赖。
代码
这里的应用场景是CD机播放光盘,所以需要准备几个bean。类的关系图如下
首先需要CompactDisc类,再次一个CDPlayer类,我们需要Spring将CompactDisc bean注入CDPlayer来实现真正的播放音乐。
public interface CompactDisc {
void play();
}
这是一个接口,其定义了CD播放机对于光盘的操作。
这时候我们还有一个实现CompactDisc接口的实现类SgtPeppers(《Sgt. Pepper's Lonely Hearts Club Band》 是英国摇滚乐队The Beatles发行于1967年6月1日的第8张录音室专辑)。
@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);
} }
这个@Component注解很关键,有了这个注解,好比该类自动告诉Spring,SgtPeppers就是一个组件类,Spring会自动为其创建bean。
使用@Component注解,Spring会默认为其创建名为sgtPeppers的bean(第一个字母小写),你也可以自定义bean的名字比如通过配置@Component("lonelyHeartsClub“”)就能创建名为lonelyHeartsClub的bean。
关于Spring会自动为其创建bean,并不完全正确,因为我还需要多做一步才能真正达到这样的效果。我们需要让Spring的组件扫描配置并开启,使得Spring能够扫描这些带有@Component或者其他注解的类。
@Configuration
@ComponentScan
public class CDPlayerConfig {
}
@Configuration表明了它是一个配置类;
@ComponentScan表明该类启用Spring的组件扫描机制,或许你看到最多或者用的最多的应该是这种<context:component-scan base-package="soundsystem">,有了@ComponentScan,我们就不需要这种方式了,是不是简洁了很多。
另外,@ComponentScan默认是扫描与配置类在相同包下面的类,当然,你也可以自定义扫描一个或多个包路径。比如配置如下
@Configuration
@ComponentScan(basePackages={"soundsystem", "video"})
public class CDPlayerConfig {
}
也可以指定扫描一个或多个类和接口比如
@Configuration
@ComponentScan(basePackageClasses={CDPlayer.class, DVDPlayer.class})
public class CDPlayerConfig {
}
下面来看看Spring是如何将CompactDisc注入到CDPlayer中的
@Component
public class CDPlayer implements MediaPlayer {
private CompactDisc cd; @Autowired
public CDPlayer(CompactDisc cd) {
this.cd = cd;
} public void play() {
cd.play();
} }
首先必不可少需要一个@Component注解以示该类收Spring管辖。
再者,我们看到在CDPlayer的构造函数上,我们使用了@Autowired注解,该注解是用来在Spring为CDPlayer创建bean的时候,通过这个构造器传入一个可设置给CompactDisc的bean,从而解决CDPlayer类对于CompactDisc的依赖问题。
除了通过构造函数注入bean还有通过setter方法注入,比如
@Autowired
publicvoidsetCompactDisc(CompactDisc cd) {
this.cd = cd;
}
甚至还可以通过将@Autowired注解用在任何类的方法上来实现依赖注入问题。
测试验证
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerTest { @Rule
public final StandardOutputStreamLog log = new StandardOutputStreamLog(); @Autowired
private MediaPlayer player; @Autowired
private CompactDisc cd; @Test
public void cdShouldNotBeNull() {
assertNotNull(cd);
} @Test
public void play() {
player.play();
assertEquals(
"Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles\r\n",
log.getLog());
} }
这一个测试类基本就能验证上面的知识点。
首先运行cdShouldNotBeNull()方法得到结果如下
该测试方法,表明通过自动化装配的方法,注入到CDPlayerTest类中的CompactDisc确实是经过Spring实例化后的bean,而不是空对象。
运行play()方法
该测试方法表明,注入到测试方法类中的MediaPlayer也是被Spring实例化过后的bean,而且可以调用该类中的play方法。
以上测试说明,Spring的自动化装配就是这么简洁高效。
另外我觉得将CDPlayer类改写如下
@Component
public class CDPlayer implements MediaPlayer { @Autowired
private CompactDisc cd; public CDPlayer() { } public void play() {
cd.play();
} }
也是可行的,并且也通过了测试,这种方式是工作中做常见的场景之一。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。
如果你觉得博主的文章对你那么一点小帮助,恰巧你又有想打赏博主的小冲动,那么事不宜迟,赶紧扫一扫,小额地赞助下,攒个奶粉钱,也是让博主有动力继续努力,写出更好的文章^^。
1. 支付宝 2. 微信
Spring实战——无需一行xml配置实现自动化注入的更多相关文章
- Spring实战之通过XML装配bean
尽管Spring长期以来确实与XML有着关联,但现在需要明确的是,XML不再是配置Spring的唯一可选方案.Spring现在有了强大的自动化配置和基于Java的配置,XML不应该再是你的第一选择了. ...
- Spring装配Bean---使用xml配置
声明Bean Spring配置文件的根元素是<beans>. 在<beans>元素内,你可以放所有的Spring配置信息,包括<bean>元素的声明. 除了Bean ...
- Spring的配置文件ApplicationContext.xml配置头文件解析
Spring的配置文件ApplicationContext.xml配置头文件解析 原创 2016年12月16日 14:22:43 标签: spring配置文件 5446 spring中的applica ...
- Spring MVC的web.xml配置详解(转)
出处http://blog.csdn.net/u010796790 1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在w ...
- spring注解机制和XML配置机制之间的比较
XML配置的优缺点: 优点有:1. XML配置方式进一步降低了耦合,使得应用更加容易扩展,即使对配置文件进一步修改也不需要工程进行修改和重新编译.2. 在处理大的业务量的时候,用XML配置应该更加好一 ...
- 一步一步深入spring(6)--使用基于XML配置的spring实现的AOP
上节我们提到了使用基于注解实现的AOP,这节我们将用基于xml配置的方式来实现的AOP. 1.首先建立一个类,作为切面类,这个类主要用来实现注解中各种通知要实现的方法. package com.yan ...
- Spring mvc的web.xml配置详解
1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在web.xml配置监听器ContextLoaderListener(l ...
- 【原】Spring和Dubbo基于XML配置整合过程
背景 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 单一应用架构 当网站流量很小时,只需一个 ...
- spring IOC注解与xml配置
转载自:https://blog.csdn.net/u014292162/article/details/52277756 IOC 1小案例 将对象的依赖交给配置文件来配置(配置文件的名字是可以任意的 ...
随机推荐
- How to let gedit of linux display "space"
gedit--> preference --> check "draw spaces" . Then gedit will display spaces
- 一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!
ViewPager的基本用法不必多说,这都很简单,我们可以在ViewPager中加载一个ImageView,也可以加载一个Fragment,这都是目前非常常见的用法.那么我今天说的是ViewPager ...
- Git使用完全解析(一)
是时候来系统的介绍一下Git了.毫无疑问,Git是目前最优秀的分布式版本控制工具,木有之一,可是我见到的很多人还是不会用,我的老东家每天忍受着SVN带来的痛苦,却迟迟不愿切换到Git上,个人感觉,许多 ...
- Android5.0之CoordinatorLayout的使用
CoordinatorLayout,中文译作协调者布局,光听这名字你可能很难判断出协调者布局有什么特点,那么我们来看看下面一张图片: 由于CSDN对图片大小的要求,我只能录制一个快速播放的动画,请大家 ...
- 微信小程序的一些限制
小程序的一些限制: 不支持HTML.没有 Dom.网页用的 JS.CSS 基本要全部重写,WXML 的语法和 HTML 差异还挺大,基本是一个个照着手册的属性去改.CSS 选择器不支持级联. 小程序源 ...
- 分享4个网址二维码API接口
说明:把url=后面的网址改成你的,四种任选一.http://pan.baidu.com/share/qrcode?w=150&h=150&url=http://lanyes.org ...
- ThinkPHP函数详解:cache方法
cache方法是3.0版本开始新增的缓存管理方法.注意:3.1.2版本后因cache方法并入原S方法,所以cache方法不再建议使用,用S方法即可. cache 用于缓存设置.获取.删除操作 用法ca ...
- ThinkPHP函数详解系列
为了能方便大家学习和掌握,在这里汇总下ThinkPHP中的经典函数用法 A 函数:实例化控制器R 函数:直接调用控制器的操作方法C 函数:设置和获取配置参数L 函数:设置和获取语言变量D 函数:实例化 ...
- react native android 开发,基础配置笔记。
一.React-native-device-info https://github.com/rebeccahughes/react-native-device-info 二.修改App名称 三.定位权 ...
- 根据id设置、获取元素的文本和value
/** * 根据id获取元素文本 * @param {String} id|元素id * return {Integer || String} text */function getText(id){ ...