## 定义Bean
### 常规定义Bean
在SpringBoot项目中,我们通常定义一个bean使用的方式如下
```java
@Component
public class Women implements Person{
public Women() {}
}
```
以上我们是通过常规方式去定义一个bean,在我们的业务代码里面比较常见。
### spring.facotories扫描bean
我们又可以通过在`resources目录`下面,新建`META-INF`目录,并新建文件`spring.factories`来完成bean的声明。

加入我们定义了两个实体类Man和Woman,并且想把这两个类定义为Bean,最终交给Spring容器去做管理。
那么可以在spring.factories中编写如下内容
```properties
org.springframework.boot.autoconfigure.EnableAutoConfiguration = \
com.example.server1.domain.entity.Man,\
com.example.server1.domain.entity.Women
```

这样就声明了两个Bean。
Man定义如下
```java
import com.example.server1.domain.Person;
public class Man implements Person{
public Man() {}
}
```
Woman定义如下
```java
import com.example.server1.domain.Person;
public class Women implements Person{
public Women() {}
}
```
#### 正确用法

不通过泛型的方式,直接指明要注入的类是Man。
如果想使用泛型也可以。可以在定义Bean的时候,加上`@Component`注解,那么如果这样做的话,其实就失去了自动配置类的意义。但是换句话来说,
**如果这个类不仅是本系统在使用,而且要抽成一个公共组件,想供给其他系统使用**,那么这个时候,`spring.factories`的自动装配必不可少,因为默认地springboot只会加载本项目中的bean,而不会加载外部依赖中的bean,外部依赖的bean一般通过`spring.factories`来进行自动装配。
总结如下:
1. 如果在本系统中使用,一个@Component足矣。
2. 如果需要被外部系统通过依赖引入,那么`@Component` + `spring.factories` 将是最佳实践。
#### 错误用法
本系统使用定义的bean,如果Man和Woman没有使用@Component注解,是没有办法使用`@Qualifier`进行选择注入的。

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

SpringBoot系列 - spring.factories应该这么玩儿