定义Bean

常规定义Bean

在SpringBoot项目中,我们通常定义一个bean使用的方式如下

1
2
3
4
5
6
@Component
public class Women implements Person{

public Women() {}

}

以上我们是通过常规方式去定义一个bean,在我们的业务代码里面比较常见。

spring.facotories扫描bean

我们又可以通过在resources目录下面,新建META-INF目录,并新建文件spring.factories来完成bean的声明。

image-20210331233701254

加入我们定义了两个实体类Man和Woman,并且想把这两个类定义为Bean,最终交给Spring容器去做管理。

那么可以在spring.factories中编写如下内容

1
2
3
org.springframework.boot.autoconfigure.EnableAutoConfiguration = \
com.example.server1.domain.entity.Man,\
com.example.server1.domain.entity.Women

image-20210331233916667

这样就声明了两个Bean。

Man定义如下

1
2
3
4
5
6
7
import com.example.server1.domain.Person;

public class Man implements Person{

public Man() {}

}

Woman定义如下

1
2
3
4
5
6
7
import com.example.server1.domain.Person;

public class Women implements Person{

public Women() {}

}

正确用法

image-20210331234405981

不通过泛型的方式,直接指明要注入的类是Man。

如果想使用泛型也可以。可以在定义Bean的时候,加上@Component注解,那么如果这样做的话,其实就失去了自动配置类的意义。但是换句话来说,

如果这个类不仅是本系统在使用,而且要抽成一个公共组件,想供给其他系统使用,那么这个时候,spring.factories的自动装配必不可少,因为默认地springboot只会加载本项目中的bean,而不会加载外部依赖中的bean,外部依赖的bean一般通过spring.factories来进行自动装配。

总结如下:

  1. 如果在本系统中使用,一个@Component足矣。
  2. 如果需要被外部系统通过依赖引入,那么@Component + spring.factories 将是最佳实践。

错误用法

本系统使用定义的bean,如果Man和Woman没有使用@Component注解,是没有办法使用@Qualifier进行选择注入的。

image-20210331234141243

虽然上面的方式,看上去没问题,并且在使用bean的时候也声明了具体的bean的name。但是通过多态的这种特性去获得bean是不可取的。会报如下异常。

image-20210331234331805