Spring in Action 第二章
来源:互联网 发布:仓库数据流程图 编辑:程序博客网 时间:2024/05/23 18:58
Spring in Action 第二章
@(Spring in Action)[spring, bean]
- Spring in Action 第二章
- Spring装配bean
- 自动化装配bean
- 创建可被发现的bean
- 为组件扫描的bean命名
- 设置组件扫描的基础包
- 通过为bean添加注解实现自动装配
- 通过Java代码装配bean显示装配
- 声明简单的bean
- 命名空间
- 导入和混合配置
- 在JavaConfig中引用XML配置还有java配置
- 在XML配置中引用JavaConfig
- 总结
- 自动化装配bean
- Spring装配bean
Spring装配bean
1.在XML中进行显式配置
2.在Java中进行显式配置
3.隐式的bean发现机制和自动装配
显式配置越少越好。当你必须要显式配置bean的时候(比如,有些源码不是由你来维护的,而当你需要为这些代码配置bean的时候),推荐使用类型安全并且比XML更加强大的JavaConfig。下面将先介绍自动化装配。
自动化装配bean
Spring从两个角度来实现自动化装配:
组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
自动装配(autowiring):Spring自动满足bean之间的依赖。
组件扫描和自动装配组合在一起就能发挥出强大的威力,它们能够将你的显式配置降低到最少。
创建可被发现的bean
创建接口:
package com.springTest;/** * @Author: YLBG-YCY-1325 * @Description: * @Date: 2017/7/21 */public interface CompactDisc { void play();}
创建带有@Component注解的CompactDisc实现类,这个简单的注解表明该类会作为组件类,并告知Spring要为这个类创建
bean。没有必要显式配置SgtPeppersbean,因为这个类使用了@Component注解,所以Spring会为你把事情处理妥当。
package com.springTest;import org.springframework.stereotype.Component;/** * @Author: YLBG-YCY-1325 * @Description: * @Date: 2017/7/21 */@Componentpublic class SgtPepper implements CompactDisc { private String title = "this is SgtPepper title"; private String artist = "The beatiles"; @Override public void play() { System.out.println("play " + title + ": artist" + artist); }}
如果你更倾向于使用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:contex="http://www.springframework.org/schema/context" 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-3.2.xsd"> <!--自动扫描包--> <contex:component-scan base-package="com.lemontree.web"/></beans>
创建配置类,@Configuration注解表明这个类是一个配置类
package com.springTest;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;/** * @Author: YLBG-YCY-1325 * @Description: 设置配置类 * @Date: 2017/7/21 */@Configuration //@Configuration注解表明这个类是一个配置类@ComponentScan // 没有包名默认是当前类包public class CDplayerConfig {}
创建测试类, 测试组件扫描能够发现CompactDisc::
package com.springTest;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ActiveProfiles;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/** * @Author: YLBG-YCY-1325 * @Description: * @Date: 2017/7/21 */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = CDplayerConfig.class)@ActiveProfiles("dev")public class CDplayerTest { @Autowired private CompactDisc cd; @Test public void testName() throws Exception { cd.play(); }}
CDPlayerTest使用了Spring的SpringJUnit4ClassRunner,以便在测试开始的时候自动创建Spring的应用上下文。注解
@ContextConfiguration会告诉它需要在CDPlayerConfig中加载配置。因为CDPlayerConfig类中包含了@ComponentScan,因此最终的应用上下文中应该包含CompactDiscbean。
为组件扫描的bean命名
两种方式命名bean:
第一种
@Component(名字)
第二种 Java依赖注入规范(Java Dependency Injection)中所提供的@Named注解来为bean设置ID
@Name(名字)
建议用@Component
设置组件扫描的基础包
为了指定不同的基础包,你所需要做的就是在@ComponentScan的value属性中指明包的名称:
@Configuration// 没有包名默认是当前类包// @ComponentScan("com.lemontree.springTest")// @ComponentScan(basePackages = "com.lemontree.springTest") @ComponentScan(basePackages = {"com.lemontree.springTest,com.lemontree.xxxx"}) public class CDplayerConfig {}
在上面的例子中,所设置的基础包是以String类型表示的。我认为这是可以的,但这种方法是类型不安全(not type-safe)的。如果你重构代码的话,那么所指定的基础包可能就会出现错误了。
除了将包设置为简单的String类型之外,@ComponentScan还提供了另外一种方法,那就是将其指定为包中所包含的类或接口:
/** * @Author: YLBG-YCY-1325 * @Description: * @Date: 2017/7/21 */@Configuration// @ComponentScan(basePackageClasses = CDplayer.class) @ComponentScan(basePackageClasses = {CDplayer.class,CompactDisc.class) public class CDplayerConfig {}
basePackageClasses属性所设置的数组中包含了类,这些类所在的包将会作为组件扫描的基础包。
通过为bean添加注解实现自动装配
@Autowired注解可以用在类的任何方法上
// 在CDplaer中驻入CompactDisc @Component("cDplayer")public class CDplayer { private CompactDisc sgtPepper; public CDplayer(CompactDisc sgtPepper) { this.sgtPepper = sgtPepper; } @Autowired public void test(CompactDisc sgtPepper){ System.out.println("test 方法 驻入"); this.sgtPepper = sgtPepper; } public CompactDisc getSgtPepper() { return sgtPepper; } public void setSgtPepper(CompactDisc sgtPepper) { this.sgtPepper = sgtPepper; }}// 测试例子@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = CDplayerConfig.class)@ActiveProfiles("dev")public class CDplayerTest { @Autowired private CompactDisc cd; @Autowired private CDplayer cDplayer; @Test public void cdshoudNotNull() throws Exception { cDplayer.getSgtPepper().play(); Assert.notNull(cDplayer); }}
上面的例子会先输出test 方法 驻入,然后打印playe()方法中的文字。如果有两个@Autowired那么会出现两次驻入
通过Java代码装配bean(显示装配)
你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component和@Autowired注解的,因此就不能使用自动化装配的方案了
声明简单的bean
注意到下例中将componentScan给去掉了,同时在方法上添加@Bean注解。因为sgtPeppers()方法上添加了@Bean注解,
Spring将会拦截所有对它的调用,并确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用。
默认情况下,Spring中的bean都是单例的,我们并没有必要为第二个CDPlayer bean创建完全相同的SgtPeppers实例。所以,Spring会拦截对sgtPeppers()的调用并确保返回的是Spring所创建的bean,也就是Spring本身在调用sgtPeppers()时所创建的CompactDiscbean。因此,两个CDPlayer bean会得到相同的SgtPeppers实例。
如果把@Bean注释掉,那么测试类那边是无法进行驻入的。
@Configurationpublic class CDplayerConfig { @Bean public CompactDisc sgtPerppers(){ return new SgtPepper(); } @Bean public CDplayer cDplayer(){ return new CDplayer(new SgtPepper()); }}
通过这种下面方式引用其他的bean通常是最佳的选择,因为它不会要求将CompactDisc声明到同一个配置类之中。在这里甚至没有要求CompactDisc必须要在JavaConfig中声明,实际上它可以通过组件扫描功能自动发现或者通过XML来进行配置。
@Configurationpublic class CDplayerConfig { @Bean public CompactDisc sgtPerppers(){ return new SgtPepper(); } @Bean public CDplayer cDplayer(CompactDisc sgtPepper){ return new CDplayer(sgtPepper); }}
带有@Bean注解的方法可以采用任何必要的Java功能来产生bean实例。构造器和Setter方法只是@Bean方法的两个简单样
例。这里所存在的可能性仅仅受到Java语言的限制。
命名空间
通过命名空间来简易化xml配置:
导入和混合配置
在JavaConfig中引用XML配置(还有java配置)
我们临时假设CDPlayerConfig已经变得有些笨重,我们想要将其进行拆分。
方式一:采用@Import,在一个JavaConfig中导入另一个JavaConfig(类似于xml配置中的 <\import resource=”xxxx”/>)
package com.lemontree.spring;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;/** * Created by lemontree on 2017/8/2. */@Configuration@Import(SpringConfig.class)public class MyConfig {}
方式二:一个更好的方法创建一个高级的JavaConfig,将另外两个导入
package com.lemontree.spring;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;/** * Created by lemontree on 2017/8/2. */@Configuration//@Import(SpringConfig.class)@Import({SpringConfig.class,SpringMVCConfig.class})public class MyConfig {}
方式三:导入Java的配置文件还不够?那就导入xml文件呗
注意:实例中没有列出复数的形式该如何写,点源码看下立马就能知道该如何写了!
package com.lemontree.spring;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.context.annotation.ImportResource;/** * Created by lemontree on 2017/8/2. */@Configuration@Import(SpringConfig.class)@ImportResource("classpath:spring.xml")//@ImportResource(locations = {"classpath:spring-mvc.xml","classpath:spring-mybatis.xml"})public class MyConfig {}
在XML配置中引用JavaConfig
假设你正在使用Spring基于XML的配置并且你已经意识到XML逐渐变得无法控制,在被无数的尖括号淹没之前,我们决定将XML配置文件进行拆分。
xml中引另外一个xml配置文件很简单,但是如何去引一个java的配置文件那?想必都能猜到,xml文件是吧,不是有<
bean/>这个标签在么,java的配置也是java类啊,直接用bean去引不就得了,哈哈。
总结
对于xml和java的配置作者是如何取舍的,看看书上原话:
总结我同时建议尽可能使用自动化配置,以避免显式配置所带来的维护成本。但是,如果你确实需要显式配置Spring的话,应该优先选择基于Java的配置,它比基于XML的配置更加强大、类型安全并且易于重构。
- Spring in Action 第二章
- 【Spring】【笔记】《Spring In Action》第二章 Bean装配
- Spring in Action 学习笔记—第二章装配Bean
- Spring in Action(第二章 装配 Bean)学习笔记
- Spring in Action 第二部分学习笔记
- JMX IN ACTION 第二章
- 《Spring in Action》第二章--自动化装配bean+音响系统例子的实现
- Spring In Action(中文第二版)读书笔记(1-1)
- Spring in Action(第二版)中文版读书笔记(1-2)
- Spring in Action(第二版)中文版读书笔记(2-1)
- Spring in Action 中文版(第二版)读书笔记(2-2)
- wxpython in action 第二章划水
- jQuery选择器(jQuery in action 第二章)
- lucene in action 第二章(索…
- 《C++ concurrency in action》第二章解析
- 《C++ concurrency in action》第二章笔记
- 学习Netty in action 第二章心得
- spring in action Third 第三章重要内容
- CSU-ACM2017暑期训练7-模拟&&贪心 A
- 程序memo
- yyy
- 计算机基础知识
- WUST OJ 1552: Stock
- Spring in Action 第二章
- STM32学习笔记之-串口中断接收不定数据buff
- RecyclerView使用完全指南
- next_permutation(排列问题)
- 数据仓库--数据建模(未完)
- JDBC总结
- IBM Ponder This November 2009【贪心】【哈夫曼树】
- jQuery自带的一些常用方法总结
- ZooKeeper 学习 (三) 客户端zkCli.sh以及相关操作命令