尽管在很多场景下通过组件扫描和自动装配实现spring的自动化装配时更为推荐的方式。但是有时候自动化配置的方案行不通,因此需要明确配置spring。比如说,你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component和@AutoWired注解的,因此就不能使用自动化装配的方案了。
spring配置Bean有两种方式:
- 第一种-显式配置:Java代码配置Bean和XML文件配置Bean。
- 第二种-自动装配:通过注解自动装配。
通过java代码配置Bean的优点:
- 更加强大:自动装配实现的功能,它都能实现,还能实现自动装配不能实现的功能。
- 容易理解:通过java代码原生态的方式来配置Bean,代码读起来也比较容易理解。
- 类型安全并且对重构友好。
注意事项:JavaConfig不应该侵入到业务逻辑代码之中。通常将JavaConfig放到单独的包中,使它与其他的应用程序逻辑分离,这样就不会对它的意图产生疑惑
1.创建配置类
创建javaConfig类的关键在于为其添加@Configuration注解,这个注解表明它是一个配置类,该类包含在spring应用上下文中如何创建bean的细节。
有一台电脑,它的配件有鼠标和键盘。此类是配置类在其类上加注解@Configuration。
ComputerConfig类如下:
@Configuration
public class ComputerConfig {
}
键盘类如下:
package javaConfigDemo;
public class Keyboard {
String channel;
String key;
public Keyboard(String channel, String key) {
this.channel = channel;
this.key = key;
}
public Keyboard() {
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
鼠标类如下:
package javaConfigDemo;
public class Mouse {
String channel;
String mouseKey;
public Mouse(String channel, String mouseKey) {
this.channel = channel;
this.mouseKey = mouseKey;
}
public Mouse() {
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public String getMouseKey() {
return mouseKey;
}
public void setMouseKey(String mouseKey) {
this.mouseKey = mouseKey;
}
}
可以看到这两个组件类并没有应用任何的注解(例如自动装配里面的组件注解@Component)
Computer类如下:
package javaConfigDemo;
public class Computer {
private Mouse mouse;
private Keyboard keyboard;
public Computer(Mouse mouse, Keyboard keyboard) {
this.mouse = mouse;
this.keyboard = keyboard;
}
public void say(){
System.out.println(mouse.getChannel()+":"+mouse.getMouseKey()+": hashcode :"+mouse.hashCode());
System.out.println(keyboard.getChannel()+":"+keyboard.getKey()+": hashcode :"+keyboard.hashCode());
}
}
在ComputerConfig配置类里面声明简单的Bean
@Bean注解括号里面的字符串就是bean的名字,也可以不加,默认bean的名字是@Bean注解所对应的方法的方法名。
这个方法返回需要创建的实例,例如computer Bean和 mouse Bean,都是利用所需类型的构造方法来返回一个与所需类型的实例,
return new Mouse("无线","3key");
return new Keyboard("1.5m","108key");
至于某些Bean需要其他类型的对象例如Computer对象的构造方法需要Mouse对象和KeyBoard对象,
public Computer(Mouse mouse, Keyboard keyboard) { this.mouse = mouse; this.keyboard = keyboard; }
针对这些可以使用下面的的方法:在创建Computer Bean的时候给它参数,使用这种方法可以将Mouse和KeyBoard类型的Bean注入到Computer Bean中。
@Bean(name = "computer") public Computer computer(Mouse mouse,Keyboard keyboard){ return new Computer(mouse,keyboard); }
还有一种不推荐的方式就是:明确的使用其他类型的@Bean方法
@Bean(name = "computer") public Computer computer(){ return new Computer(mouse(),keyboard()); }
综上,创建的ComputerConfig类如下:
@Configuration
public class ComputerConfig {
@Bean(name = "mouse")
public Mouse mouse(){
return new Mouse("无线","3key");
}
@Bean(name = "computer")
public Computer computer(Mouse mouse,Keyboard keyboard){
return new Computer(mouse,keyboard);
}
@Bean(name = "keyboard")
@Scope("prototype")
public Keyboard keyboard(){
return new Keyboard("1.5m","108key");
}
}
测试:
获取上下文:
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(javaConfigDemo.ComputerConfig.class);
public class Main {
public static void main(String[] args) {
//注意这里不可以加双引号
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(javaConfigDemo.ComputerConfig.class);
Computer computer=(Computer)applicationContext.getBean("computer");
computer.say();
computer.say();
computer.say();
}
}
结果: