Spring4.0学习笔记 第二章 自动装配

2016-12-30 23:00

Spring容器负责创建应用程序中的bean,并通过DI来协调这些对象的关系。

Spring提供了三种主要装配bean的机制:

1、在XML中显示配置

2、在Java中进行显式配置

3、隐式的bean发现和自动装配

建议尽可能地使用自动装配机制,显式配置越少越好。当年必须使用显式配置的时候(比如,有些源码不是你来维护的,当你需要为这些代码

配置bean的时候,因为源码可能没有@Component @Configuration 注解),推荐使用 类型安全并且比XML更加强大的JavaConfig

自动化装配Bean:

Spring 从两个角度实现自动化装配bean:

1、组件扫描(Component scanning):Spring会自动发现应用上下文中所创建的bean(该bean带有@Component @Service @Controller @Reposity任意一 种注解都可以)

2、自动装配(autowiring):spring自动满足bean之间的依赖(自动注入依赖)

例如以下例子:

目录结构Spring4.0学习笔记 第二章 自动装配0


先看下JavaConfig 上下文配置类:

//@ComponentScan(basePackages={"interfaces","xxx"})中括号里面用逗号隔开,可以指定扫描多个包,

//如果不指定扫描的包,则会默认扫描跟配置类同一个包中的类文件

package config;

import interfaces.MarkIf;


import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//@ComponentScan(basePackages="interfaces") 或者@ComponentScan("interfaces")
//@ComponentScan(basePackages={"interfaces"})
@Configuration//该注解对spring容器说我是 配置文件
@ComponentScan(basePackageClasses=MarkIf.class)//该注解表示扫描该类所在包中的所有bean组件
//这种方式比上面使用字符创的方式更好,因为如果代码重构删掉包了就可能造成错误, 当然这种方式我们最好不要使用我们
//有用的bean类,可以在要扫描的包中创建一个标记类方便spring扫描,例如MarkIf.class就是一个空的标记类
public class TestConfig {
}

package interfaces;
/**
 *    标记类
 * spring java配置类默认扫描与该配置类下面的所有注解的bean,但是项目中
 * 我们的bean 往往不会在跟配置类在一个包中,这时我们可以指定扫描的包,如下
 * @CompentScan(basePackages={"pack1",pack2}),
 * 但是通过字符串指定包名 不够安全,因为如果代码有的包名被移除了就会发生错误,
 * 所以spring,提供了@ComponentScan(basePackageClasses={MarkIf.class}),
 * 扫描该接口或者该类所在的包 中的所有 注解 生成bean
 * @author Administrator
 *
 */

public interface MarkIf {


}

 创建接口:

package interfaces;


public interface DiskInterface {

void play();


}

实现类:

package interfaces;


import org.springframework.stereotype.Component;


@Component//要使用自动准备必须加该注解,spring容器扫描看到该注解,则容器帮我们生成该对象
public class JayDisk implements DiskInterface {

public void play() {
System.out.println("sing song");
}


}

使用Junit4测试:

package interfaces;


import javax.annotation.Resource;


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


import config.TestConfig;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=TestConfig.class)//加载配置文件
public class CDPlayer {

// @Autowired 自动注入接口的实现
// @Qualifier("diskImpl")//因为autowired默认是按照类型注入的,即按照接口的去找实现类注入,如果有多于一个以上的该接口实现spring会报错不懂

//要选哪个实现类注入,使用Qualifier指定具体的bean id,跟autowired配合一起使用,这样即使有多个实现也不会报错了。 spring默认的bean Id为该类的类名

//首字母小写作为bean ID,当然也可以手动指定自己想要的bean id,像这样@Component("dsk")或者@Component(value="dsk")

@Resource(name="dsk")//该注解按照指定的bean id去找到对应的bean进行注入,它等价于@Autowired @Qualifier("dsk")

//尽量使用它代替autowired,因为它是java自带实现的,不是由spring框架实现的,能降低与spring的耦合, resource默认

//按照name=bean id匹配,当根据name找不到的时候,会按照类型去找就跟autowired一样,此时如果有大于一个以上的实现类,也是会报错的
private DiskInterface di;

@Test
public void sing(){

di.play();
}



}