spring提供了三种主要的bean装配机制:
在XML中进行显示配置;
在java中进行显示配置;
隐式的bean发现机制和自动装配;
其中
spring从两个角度实现自动化装配:
组件扫描(component scanning):spring会自动发现应用上下文中创建的bean;
自动装配(autowiring):spring自动满足bean之间的依赖;
1.spring自动化装配bean
1.1组件扫描
1.1.1创建可被发现的bean
public interface CompactDisc {
void play();
}
@Component
public class SgtPeppers implements CompactDisc {
private String title = "title";
private String artist = "the beatles";
public void play() {
System.out.println("playing " + title + "by " + artist);
}
}
注意@Component注解,这个注解表明该类会作为组件类,并告知spring要为这个类创建bean;
但是组件扫描默认不启用,需要显示配置spring从而命令它去寻找带@Component的类,并创建bean;如下所示:
@Configuration
@ComponentScan
public class CDplayerConfig {
}
@ComponentScan会启用组件扫描;它会默认扫描与配置类相同的包;
也可以使用xml来启用组件扫描,即spring 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:context="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.xsd">
<context:component-scan base-package="chapter2" />
</beans>
1.1.2为组件扫描的bean命名
spring应用上下文中所有bean都会给定一个ID,如果没有显示指定,sping默认将类名的首字母小写,作为bean的id;
可以显示指定bean的id(有2中方法):
第一种:
@Component("heartsClub")
public class SgtPeppers implements CompactDisc {
第二种:
@Named(“name”)
@Named可以作为@Component注解的替代方案,但有一些细微差别。
1.1.3 设置组件扫描的基础包
@Configuration
@ComponentScan(basePackages={"package1", "package2"})
public class CDPlayerConfig{}
这种缺点是,如果重构代码,所指定的基础包会出现错误;
所以可以将其指定为包里所含的类或接口,这些类所在的包将会作为组件扫描的基础包:
@Configuration
@ComponentScan(basePackages={CDPlayer.class, DVDPlayer.class})
public class CDPlayerConfig{}
1.2.自动装配
自动装配就是让Spring自动满足bean依赖的一种方法。
自动装配可以借助@Autowired注解。
@ComponentScan
public class CDPlayer {
private CompactDisc cd;
@Autowired
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
}
@Autowired可以用在构造器、Setter方法。
@Autowired
public void insertDisc(CompactDisc cd) {
this.cd = cd;
}
如果没有匹配的bean,在创建应用上下文时,spring会抛异常,可以@Autowired(required=false),则spring会让这个bean处于未装配状态。
如果有多个bean都满足依赖关系时,spring会抛出异常;
@Autowired也可以用@Inject替代;(@Inject/@Named来源于java依赖注入规范)
2.装配bean
2.1java代码装配bean
组件扫描与自动装配有时行不通,例如想要将第三方组件装配到应用中时,可以显式装配,方法是java代码/XML装配;
创建配置类
@Configuration
注解表明某个类是配置类,该类包含在spring 应用上下文中创建bean的细节。
springxml文件中,装配bean的最基本的XML元素位于spring-bean模式之中,是该模式的一个元素,是spring配置文件的根元素。
声明简单的类
@Bean
public SgtPeppers sgtPeppers(){
return new SgtPeppers();
}
@Bean告诉spring这个方法会返回一个对象,这个对象要被注册为spring应用上下文中的bean;
等同的XML配置为:
<bean class="com.SgtPeppers" id="sgtPeppers">
这里如果id没定义,默认是com.SgtPeppers#0,之后默认数字递增。最好定义id。
当spring发现这个bean时,会调用默认构造器创建bean;这点没有java创建强大,java可以随意通过各种方法创建bean;
借助spring tool suite,spring的IDE检查配置的合法性;
注入bean
@Bean
public CDPlayer cdPlayer() {
return new CDPlayer(sgtPeppers());
}
这里注意,因为sgtPeppers()方法上添加了@Bean注解,spring会拦截所有对他的调用,并确保直接返回该方法所创建的bean;
默认情况下,spring创建的bean都是单例的。
XML注入,采用构造器注入/
构造器注入:
<bean id="cdplayer" class="com.Cdplayer">
<constructor-arg ref="sgtPeppers"/>
<constructor-arg value="sgtPeppers"/>
</bean>
也可使用c命名空间;
java配置类中引入xml配置文件的方法:
@ImportResource("classpath:test-config.xml");
xml中引入java配置类的方法:
<bean class="com.competDisc"/>