Spring实战之二:装配Bean
来源:互联网 发布:centos mirror 163 编辑:程序博客网 时间:2024/05/17 23:39
2.1 Spring配置的可选方案
Spring提供了三种装配机制:
- 在XML中显式配置
- 在Java中显式配置
- 隐式的bean发现机制和自动装配
Best Practice:尽可能使用自动配置的机制,必须使用显式配置时,优先选择JavaConfig
2.2 自动化装配bean
从两个角度实现自动化装配:
- 组件扫描:自动发现应用上下文创建的bean
- 自动装配:自动满足bean之间的依赖
2.2.1 创建可被发现的bean
相关注解:
- Component:表明该类为组件类,需要为该类创建bean
- ComponentScan:默认会扫描与配置类相同的包及其子包
- Runwith:junit的注解,和SpringJUnit4ClassRunner类一起,在测试开始时自动创建Spring的应用上下文
- ContextConfiguration:告知去加载哪个配置类
- Autowired:告诉Spring这里需要注入一个bean
- Configuration:表明该类为配置类
- Bean:告诉Spring该方法会返回一个对象,要把该对象注册到应用上下文中去
默认情况下并不启用组件扫描,所有我们还需显式配置一下。
2.2.2 为组件扫描的bean命名
如果不指定的话,Spring扫描到的bean的id为其类名,但第一字母小写,如果想给bean指定一个id,可以用一下方式:
@Component("beanName")
2.2.3 设置组件扫描的基础包
如果不指定,@ComponentScan会以配置类所在的包为基础包,我们可以显示地指定要扫描的基础包,特别是当我们想把所有配置类单独放置到一个包中时。可以用以下几种方式指定包名:
@CompenentScan("soundsystem")
@CompenentScan(basePackages = "soundsystem")
@CompenentScan(basePackages = {"soundsystem","video"})
@CompenentScan(basePackageClasses = {CDPlayer.class,DVDPlayer.class})
2.2.4 为bean添加注解实现自动装配
在满足依赖的过程中,Spring会在应用上下文寻找匹配某个bean需求的其他bean。通过@Autowired注解可以表明某个地方需要注入一个bean。Autowired注解可以放在成员变量,构造方法,setter,甚至是其他方法上,Spring会尝试满足方法参数上所声明的依赖。
如果没有bean匹配需求的话,会抛出异常,可以将注解的required属性设为false来避免异常的出现。多个bean满足需求时,也会抛出一个异常。
@Autowired约等于@Inject
通过Java代码装配bean
某些情况下无法使用自动扫描,比如要把第三方组件装配到应用中,此时可以采用显式装配方式,显式装配有两种方案:Java和XML。要注意,JavaConfig是配置代码,不应该包含任何业务逻辑,通常把JavaConfig放到单独的包里去。
2.3.1 创建配置类
创建配置类的关键在于为其添加@Configuration注解,该注解表明这是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。
2.3.2 声明简单的bean
要在JavaConfig中声明bean,需要编写一个方法,这个方法会创建所需类型的实例,然后给这个方法添加@Bean注解,告诉Spring该方法会返回一个对象,要把该对象注册到应用上下文中去,代码示例如下:
@Bean public CompactDisc sgtPeppers(){ return new SgtPeppersCD(); }
这种方式创建的bean默认的名字和方法名是一样的,可以显式地为bean指定名字:
@Bean(name="myBean")
借助JavaConfig实现注入
在JavaConfig中装配bean最简单的方式就是引用创建bean的方法,示例代码如下:
@Bean public CDPlayer cdPlayer(){ return new CDPlayer(sgtPeppers()); }
上述代码中,cdPlayer方法使用了@Bean注解,表明了该方法会创建一个bean实例并注册到应用上下文中,而创建CDPlayer对象时,需要为该对象注入一个CompactDisc类型的依赖,表面上,该依赖是通过调用sgtPeppers()方法得到的,但由于sgtPeppers()方法上添加了@Beanz注解,Spring会拦截所有对它的调用,并确保直接返回该方法创建个bean,而不是每次都对其进行实际调用。所有实际上cdPlayer所需的依赖是从应用上下文中得到的。默认情况下,Spring中的Bean都是单例的。通过调用方法来应用bean的方式有点让人困惑,还有一种更好的方式如下:
@Bean public CDPlayer cdPlayer(CompactDisc compactDisc){ return new CDPlayer(compactDisc); }
Spring使用该方法创建Bean是,会自动装配一个CompactDisc到配置方法中。这种方式通常是最佳选择,它不会要求其依赖的bean要在同一个配置类这种创建,甚至没有要求依赖的bean要在JavaConfig 中声明,它可以是通过组件扫描或是XML来进行配置的。
带有@Bean注解的方法的方法体中可以以任意方式实现bean的创建。
通过XML装配bean
Spring刚开始时就是使用XML作为主要的配置方式的。学习本部分内容主要是来帮助我们维护已有的XML配置,在完成新的Spring工作时,我们最好使用自动化配置和JavaConfig。
2.4.1 创建XML配置规范
beans元素是所有Spring配置文件的根元素。
声明一个简单的bean
bean元素和@Bean注解有点类似,如下通过bean元素来声明一个bean:
<bean class="soundsystem.SgtPeppersCD"></bean>
没有明确指定id时,这个bean会根据全限定类名来命名,如上述bean的id将会是:soundsystem.SgtPeppersCD#0
。其中,#0是一个计数形式,用来区分相同类型的其他bean。如果再声明一个相同的bean,它的id将会是:soundsystem.SgtPeppersCD#1
。
我们通常还是要为bean指定id的,因为稍后要引用它的话得通过id来引用,以下方式更为规范:
<bean id="compactDisc" class="soundsystem.SgtPeppersCD"></bean>
但为了减少繁琐的配置,那些不需要通过id引用的bean就不用指定id了。
这种方式比起JavaConfig的缺点如下:
- JavaConfig可以在方法体中以任意方式创建bean,而xml方式bean的创建无需我们负责
- bean的类型以字符串的方式设置在class属性中,在编译时无法进行类型检查,如果重命名了类,就会报错
借助构造器注入初始化bean
在xml方式中,只有一种声明bean的方式,即使用bean元素并指定class属性,但在注入依赖时,会有多种配置方案。比如构造器注入就有两种方案:
- constructor-arg元素
- 使用Spring3.0引入的c命名空间
使用constructor-arg元素比较冗长,但功能比较c命名空间强大。
构造器注入bean引用
通过构造器的方法示例如下:
<bean id="cdPlayer" class="soundsystem.CDPlayer"> <constructor-arg ref="compactDisc"></constructor-arg> </bean>
通过c命名空间的示例如下:
<bean id="cdPlayer2" class="soundsystem.CDPlayer" c:cd-ref="compactDisc"/>
指定构造器的属性以c:开头,后面跟的是构造器参数名,最后的-ref表明正在装配的是一个bean的引用而不是一个字符串。上述代码还有以下两种表示方式:
<bean id="cdPlayer2" class="soundsystem.CDPlayer" c:_0-ref="compactDisc"/>
<bean id="cdPlayer2" class="soundsystem.CDPlayer" c:_-ref="compactDisc"/>
将字面量注入到构造器中
以下为本节要使用到的实体类的代码:
package soundsystem;public class BlankDiscCD implements CompactDisc { private String title ; private String artist ; public BlankDiscCD(String title, String artist) { this.title = title; this.artist = artist; } public void play() { System.out.println("Playing "+title + " by " + artist); }}
可以看到上述实体类中的构造器的参数都是非引用类型,在xml配置该bean的方式如下:
<bean id="blankCD" class="soundsystem.BlankDiscCD"> <constructor-arg value="i am title"/> <constructor-arg value="i am artist"/> </bean>
使用c标签的方式如下:
<bean id="blankCD2" class="soundsystem.BlankDiscCD" c:_title="titleStr" c:_artist="artistName" />
装配集合
装配集合使用set或list元素,两种元素的作用是一样的,可以用来装配Set,List甚至是数组
2.4.4 设置属性
调用setter方法来设置属性的方式如下:
<bean id="cdPlayer3" class="soundsystem.CDPlayer" > <property name="cd" ref="compactDisc"></property> </bean>
以上设置会在装配时调用CDPlayer的setCd方法把compactDisc注入进去。
与构造器的c标签类似,这里也可以使用p标签,对于p标签,在此就不再赘述,需要用到的时候翻阅书本或查找文档就可以。
2.5 导入和混合配置
2.5.1 在JavaConfig中引用XML配置
我们先看一下以下JavaConfig:
package soundsystem;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.context.annotation.ImportResource;@Configuration@Import(CDPlayerConfig.class)@ImportResource("classpath:cd-config.xml")public class SoundSystemConfig {}
在上述的JavaConfig中,我们使用Import注解引用了另一个JavaConfig,使用ImportResource引用了一个xml配置。
2.5.2 在XML配置中引用JavaConfig
我们先看一下以下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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="soundsystem.CDPlayerConfig"/> <import resource="cd-config.xml"/></beans>
在上述xml配置中,我们使用了bean元素来引入JavaConfig,使用import元素来引入其他xml配置
- Spring实战之二:装配Bean
- Spring之装配bean(二)
- Spring实战--(二)装配Bean
- Spring实战-装配bean
- spring 装配bean(二)
- 【Spring】Spring实战(二)——装配Bean
- Spring学习笔记(二) --- 装配Bean之自动化装配
- spring实战-自动装配bean
- spring实战-注解装配bean
- spring实战-JavaConfig装配bean
- spring实战-混合装配bean
- spring实战-条件装配bean
- spring实战-注解装配bean
- Spring实战(装配Bean)
- Spring之装配Bean
- 《Spring实战》系列之Bean的装配-Days01
- 《Spring实战》系列之Bean的装配-Days02
- Spring(二)--Bean装配
- [转]ExtJS学习------Ext.window属性详解
- 简单的频道管理(第一步)
- DirectX9学习(一)
- 使用spring jdbc查询对象
- 写给立志做码农的大学生
- Spring实战之二:装配Bean
- Java NIO系列教程(七) FileChannel
- linux 管道、消息队列、共享内存的对比
- 【C++】多线程整理
- VS 2017 安装了一下午
- 常见面试编程题
- [iOS] 使用WebViewJavascriptBridge实现OC与JS交互
- Intellij idea 错误提示信息不能复制的问题
- phpcms 近期项目总结