1. 背景
上一篇讲了xml配置中如何装配bean,其实注解配置中装配bean的原理与xml一模一样,而且达到的效果也是相同的,不过是采用了不同的方式而已。
所以本篇我们也并不更换实例,还是以在舞台中注入歌手、舞者为例,进行装配。由于注解情况下,都是直接在类、属性上添加注解,没有必要显示指定bean的包路径+类名,所以都是自动装配。
2. 按名称自动装配
我们对bean进行命名,同时在装配时指定装配的bean名称。
2.1 定义歌手类,并通过@component注解为其生成对应bean。
package org.maoge.annotationassemble;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("liujia") // 通过注解指定Dancer类生成的bean名称为liujia
public class Dancer {
@Value("刘迦") // 通过注解注入姓名
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package org.maoge.annotationassemble;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("daolang") // 通过注解指定Singer类生成的bean名称为daolang
public class Singer {
@Value("刀郎") // 通过注解注入姓名
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
此处再次解释下@Component("xxx")注解的作用,Spring容器在启动时,会扫描该注解标注的类,并生成一个命名为xxx的bean对象放入容器中。如果使用注解@Component标注,则生成bean的命名为类的首字母转小写。
2.2 定义舞台类,并指定名称装配其属性
可以通过@Autowired使bean通过指定规则注入进来,同时使用@Qualifier("xxx")装配命名为xxx的bean,代码如下:
package org.maoge.annotationassemble;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
//舞台类,注意舞台也要生成一个bean
@Component("stage")
public class Stage {
@Autowired//表示自动注入
@Qualifier("daolang")//指定要装配名称为daolang的bean
private Singer singer;
@Autowired
@Qualifier("liujia")//指定要装配名称为liujia的bean
private Dancer dancer;
public Singer getSinger() {
return singer;
}
public void setSinger(Singer singer) {
this.singer = singer;
}
public Dancer getDancer() {
return dancer;
}
public void setDancer(Dancer dancer) {
this.dancer = dancer;
}
}
2.3 配置xml文件,开启对bean的扫描
不要忘记使用注解配置bean时,还是需要一个xml文件,其中要开启对bean所在包的扫描,所以spring.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"
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-4.0.xsd">
<context:component-scan
base-package="org.maoge.annotaionassemble" />
</beans>
2.4 测试
启动主类,从容器中获取舞台,会发现舞台中的歌手和舞者均已装配成功。
package org.maoge.annotationassemble;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"/org/maoge/annotationassemble/spring.xml");
Stage stage = (Stage) context.getBean("stage");
System.out.println(stage.getSinger().getName());
System.out.println(stage.getDancer().getName());
}
}
输出结果:
刀郎
刘迦
3. 按类型自动装配
这个就更加简单了啊,因为使用注解时,一般一个类就生成一个bean(一个注解加到一个类上,生成一个对应bean)。
所以按类型匹配基本上很稳啊,没啥问题,也非常流程。目前这种方式应该是非常非常流行的,不论是SSM项目还是SpringBoot项目,这种方式都使用的非常多。
看例子:
3.1 定义歌手类和舞者类
package org.maoge.annotationassemble;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component // 未指定命名,所以默认命名应为singer
public class Singer {
@Value("刀郎") // 通过注解注入姓名
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package org.maoge.annotationassemble;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component // 未指定命名,所以默认命名应为dancer
public class Dancer {
@Value("刘迦") // 通过注解注入姓名
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.2 通过类型自动装配舞台bean
不用加@Qualifier,默认就是自动按类型装配,因为太常用了。
package org.maoge.annotationassemble;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Stage {
@Autowired // 按类型自动装配
private Singer singer;
@Autowired // 按类型自动装配
private Dancer dancer;
public Singer getSinger() {
return singer;
}
public void setSinger(Singer singer) {
this.singer = singer;
}
public Dancer getDancer() {
return dancer;
}
public void setDancer(Dancer dancer) {
this.dancer = dancer;
}
}
3.3 测试运行
还是同样的xml和Main.java,直接运行Main进行测试,依然没问题。
4. 总结
在使用注解时,实现了装配的高度自动化,非常锋利。
装配这个事,并不复杂,就是往一个bean的属性中注入其他bean。
自动装配,就是指定要装配的bean的类型或者名称,然后指定自动装配的规则(名称/类型),然后由容器自动将相应bean注入被装配bean的属性。