读《Spring 实战(第四版)》第二章 装配Bean

Spring的三种主要装配机制
  • 在XML中进行显示配置
  • 在Java中进行显示配置
  • 隐式的bean发现机制和自动装配
    • 组件扫描
    • 自动装配

@ComponentScan 注解默认会扫描配置类所在的包

@Component
@componentScan
public Class CDPlayerConfig {
} 

相同的功能用xml配置的话 使用Spring context命名空间1<context:component-scan>元素

<context:component-scan base-package="org.springsz.chapter2"/>
有多个基础包时用,隔开
<context:component-scan base-package="org.springsz.chapter1, org.springsz.chapter2"/>

测试:
新建测试类CDPlayerTest

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDTest {

    @Autowired
    private CompactDisc cd;

    @Test
    public void cdShouldNotBeNull() {
        Assert.assertNotNull(cd);
    }

}

使用SpringSpringJUnit4ClassRunner,以便在测试开始的时候自动创建Spring的应用上下文
@ContextConfiguration告诉需要在CDPlayerConfig中加载配置,因为CDPlayerConfig中包含@ComponentScan,所以最终应用上下文包含CompactDisc bean

@Component("lonelyHeartsClub") //为组件扫描的bean命名
@Component //默认扫描本类所在的包
@Component("soundsystem") //设置扫描的基础包
@Component(basePackages = "soundsystem") 
@Component(basePackages = {"soundsystem", "video"}) //设置多个基础包
@Component(basePackageClasses = {CDPlayer.class, DVDPlayer.class}) //设置类所在的包为基础包

@Autowired注解可以用在属性、构造器、方法上,如果没有匹配的bean,那么在应用上下文创建的时候,Spring会抛出异常
@Autowired(required=false) 没有匹配的bean的时候不会抛异常
如果有多个bean满足依赖关系,会抛出异常

  • 书里面是提倡用Spring自动装配bean、JavaConfig显示装配bean
  • 上面是自动装配的例子,下面这个是显示装配的例子
  • 比如要使用第三方库中的组件,没办法添加@Componen和@Autowired注解,可以使用JavaConfig显示配置bean

@Bean 注解会告诉Spring这个方法会返回一个对象,注册为Spring应用上下文中的bean

@Bean  //@Bean("lonelyHeartsClubBand")
public CompactDisc sgtPeppers() {
	return new SgtPeppers();
}
······························································
@Configuration
@ComponentScan
public class CDPlayerConfig {  //创建配置类

	@Bean                      //返回对象注册到Spring应用上下文中
    public CompactDisc sgtPeppers() {
        return new SgtPeppers();
    }

}

默认bean的id是方法名,可以设置别名
Spring将会拦截对@Bean注解方法的调用,并确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用。

@Configuration
@ComponentScan
public class CDPlayerConfig {

    @Bean
    public CompactDisc sgtPeppers() {
        return new SgtPeppers();
    }
	@Bean
    public CDPlayer anotherCdPlayer() {
        return new CDPlayer(sgtPeppers());
    }
    @Bean
    public CDPlayer cdPlayer(CompactDisc cd) { //当Spring调用此方法时,会自动装配一个CompactDisc到配置方法中,不用明确引用CompactDisc的@Bean方法
        return new CDPlayer(cd);
    }
}

作为起步,在JavaConfig中所需要的只是@Configuration
在XML中需要在顶部声明多个XML模式(XSD)文件,这些文件定义了配置Spring的XML元素。

<bean class="soundsystem.SgtPeppers" /> //默认ID是:soundsystem.SgtPeppers#0,#0是一个计数形式,用来区分相同类型的其他bean,#1
<bean id="sgtPeppers" class="soundsystem.SgtPeppers" />

Spring发现<bean>,会调用默认构造器创建bean

<!--注入bean-->
<bean id="cdPlayer" class="soundsystem.CDPlayer">
	<constructor-arg ref="sgtPeppers" />
</bean>
<!--还可以使用c-命名空间,需要顶部模式声明-->
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:cd-ref="sgtPeppers"></bean>
<!--c 代表c命名空间前缀-->
<!--cd 代表构造器参数名-->
<!--ref 代表注入bean引用-->
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_0-ref="sgtPeppers"></bean>
<!--_0 表示参数索引-->
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_-ref="sgtPeppers"></bean>
<!--只有一个参数可以只写_-->
不使用ref引用其他bean的例子:
首先有个类
public class BlankDisc implements CompactDisc {

    private String title;
    private String artist;

    public BlankDisc(String title, String artist) {
        this.title = title;
        this.artist = artist;
    }
	public void play() {
        System.out.println("Playing " + title + " by " + artist);
    }
}
······································································
<bean id="blankDisc" class="soundsystem.BlankDisc">
	<constructor-arg value="" />
	<constructor-arg value="" />
</bean><bean id="blankDisc" class="soundsystem.BlankDisc" c:_title="" c:_artist="" /><bean id="blankDisc" class="soundsystem.BlankDisc" c:_0="" c:_1="" />
<!--在装配集合参数时,只能使用<constructor-arg>-->
<constructor-arg>
	<list>
		<value>aabbccdd</value>
	</list>
</constructor-arg><constructor-arg>
	<list>
		<ref bean="sgtPeppers" />
	</list>
</constructor-arg><list>换为<set>也一样

<!--还可以将null传给构造器-->
<constructor-arg><null/></constructor-arg>

以上的注入都是XML使用构造器的注入
下面是属性注入

<bean id="blankDisc" class="soundsystem.BlankDisc">
	<property name="title" value="" />
</bean>

<bean id="cdPlayer" class="soundsystem.CDPlayer" >
	<property name="cd" ref="sgtPeppers">
</bean>
<!--或者使用p-命名空间-->
<bean id="cdPlayer" class="soundsystem.CDPlayer" p:cd-ref="sgtPeppers" />

<!--对于集合属性,和构造器注入一样-->
<property name="tracks">
	<list>
		<value>aabbccdd</value>
	</list>
</property>

<!--还可以通过使用util-命名空间进行简化-->
<!--同样需要顶部模式声明-->
<!--他会创建一个bean,提供引用-->
<util:list id="trackList">
	<value>aabbccdd</value>
</util:list>
<bean id="##" class="##" p:title="##" p:artist="##" p:tracks="trackList" />

<!--util-命名空间还提供其他类型元素-->
<util:map><util:set> ......

下面看下JavaXML的混合配置

//假设现在有两个配置类,JavaConfig1和JavaConfig2
@Configuration
public class JavaConfig1 {
}

@Configuration
public class JavaConfig2 {
}

//两个类中相互有bean的引用,现在需要整合两个类
//方法一:
@Configuration
@import(JavaConfig2.class)
public class JavaConfig1 {
}
//方法二:
//新建一个根配置类
@Configuration
@import({JavaConfig1.class, JavaConfig2.class})
public class JavaConfigAll {
}

//如果在Java中需要用到XML中的配置bean:
@Configuration
@import({JavaConfig1.class, JavaConfig2.class})
@importResource("classpath:cd-config.xml")
public class JavaConfigAll {
}

//再假设现在有两个XML配置文件,相互有bean引用,现在要整合
//在config1.xml中:
<import resource="config2.xml" /> //这里我的书上写的是resoune,应该是印错了

//在XML中想要引用JavaConfig的类时,可以使用<bean>元素

//XML中也可以设置一个根配置文件,整合各个XML和JavaConfig
//configAll.xml:

<bean id="" class="" />
<import resource="config1.xml" /> //这里resource书上印对了
<import resource="config2.xml" />

再在根配置中启动组件扫描

  1. ** ↩︎

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值