Spring装配bean
创建应用对象之间的协作关系的行为通常称为装配,是依赖注入(DI)的本质。
依赖注入很好理解。这里可以简单了解一下:https://blog.csdn.net/yuanyuan214365/article/details/52900414
Spring具有非常大的灵活性,它提供了三种主要的装配机制:
1、隐式的bean发现机制和自动装配
2、在Java中进行显示配置
3、在XML中进行显示配置
推荐尽可能地使用自动配置的机制,显示配置越少越好。
但是当你必须要显示配置bean的时候(例如源码并非你维护,而你必须为这些代码配置bean),推荐使用比XML更加强大的JavaConfig。最后只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时,才应该使用XML。
隐式的bean发现机制和自动装配
Spring从两个角度来实现自动化装配:
组建扫描:自动发现应用上下文中所创建的bean
自动装配:自动满足bean之间的依赖
1、创建可被发现的bean
随便假设这三个:车轮,座位,引擎。是车类需要依靠的组件,每个类各自有自己的方法。
@Component
class Wheel {
public void roll(){
System.out.println("Wheels are rolling.");
}
}
@Component
class Seat {
public void seat(){
System.out.println("People sitting in the seats.");
}
}
@Component
class Engine {
public void start(){
System.out.println("Engine start.");
}
}
这里注意要有@Component注解,这个注解表明该类会作为组件类,并告知Spring要为这个类创建bean。因为有了这个注解,Spring会为你把配置bean的事情处理妥当。
现在组件有了,还需要一件东西要去取寻找组件。
2、创建组件扫描配置类
这个很简单,只需要两个注解。
@Configuration
@ComponentScan
class Config {
}
@Configuration注解表示是配置类,@ComponentScan注解能够在Spring中启用组件扫描,Spring会查找带有@Component注解的类,并会在Spring中自动为其创建一个bean。
@ComponentScan(“packagename”)如果是这样的注解,Spring将会在packagename包中扫描组件,如果没有参数,则将会在配置类的包中扫描。
3、自动装配
interface Transportation {
void run();
void stop();
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=Config.class)
public class Car implements Transportation {
@Autowired
private Wheel wheel;
@Autowired
private Seat seat;
@Autowired
private Engine engine;
@Test
public void run() {
seat.seat();
engine.start();
wheel.roll();
System.out.println("The car has run.");
}
@Test
public void stop() {
System.out.println("Now, the car has stopped.");
}
}
返回结果:
People sitting in the seats.
Engine start.
Wheels are rolling.
The car has run.
Now, the car has stopped.
@ContextConfiguration(classes=Config.class)表明了配置类的所在,这个Car类将会从Config配置类中获得扫描到的组件,然后通过@Autowired注解自动匹配,将bean注入给各个属性。
@RunWith(SpringJUnit4ClassRunner.class)会在测试开始的时候自动创建Spring的应用上下文,用于单元测试,而不需要一次次繁杂的启动整个容器。(需要有相关环境,具体百度junit4)
大体就是这样了,也不需要XML,只用java code,是非常方便也是非常推荐的方式。
4、处理歧义性
@Autowired固然强大,但是如果有不止有一个bean能否匹配的话,就会阻碍自动装配。
有两种方式处理:
1、表示首选的bean:只需要在组件类前面加一个@Primary注解即可,这样如果有多个bean匹配,就会先注入此组建类。
2、限定自动装配的bean:@Qualifier(“beanid”)注解
@Component
@Qualifier("cold")
class IceCream implements Dessert{
//code
}
@Component
@Qualifier("crispy")
class Cookies implements Dessert{
//code
}
@Autowired
@Qualifier("cold")
public void setDessert(Dessert dessert){
this.dessert = dessert;//这里就会将IceCream注入进来
}
@Bean//也可以在显式装配Bean时使用
@Qualifier("crispy")
public Cookie cookie(){
return new Cookie();
}
可以有多个@Qualifier注解来筛选出特定的一个bean,不过同一条目上重复出现相同类型的多个注解,得要再加一个@Repeatable注解(Java8后可用)。