如何将自己开发的 Bean 装配到 Spring IOC 容器中,大部分情况下我们可以使用 ApplicationContext 的具体实现类,因为对应的 Spring IOC 容器功能强大,在 Spring 当中提供了3中方式进行配置:
- XML配置
- Java的接口和类中实现配置
- 隐式Bean的发现机制和自动装配原则
XML配置Bean
<bean id="source" class="com.ssm.entity.Source">
<property name="fruit" value="橙汁"/>
<property name="sugar" value="少糖"/>
<property name="size" value="大杯"/>
</bean>
<bean id="juiceMaker" class="com.ssm.entity.JuiceMaker">
<property name="beverageShop" value="贡茶"/>
<property name="source" ref="source"/>
</bean>
id 属性是 Spring 找到这个 Bean 的编号,id 不是必须的属性,如果没有声明 id,Spring 会采用“全限类名#{number}”的格式生成编号。
class 是一个类的全限定名。
property 元素是定义类的属性,name 属性定义属性名称,value 定义值。
ref 属性是引用对应的 Bean 的 id。
注解配置Bean
在 Spring3.0 之后已经不再推荐使用 XML 的方式装配 Bean,更多时候推荐使用注解配置,使用注解可以大量减少 XML 的配置代码,注解既能实现 XML 的功能,也提供了自动装配的功能,满足了“约定优于配置”的开发原则。
Spring 中提供了两种方式让 Spring IOC 容器发现 Bean:
- 组件扫描:通过定义资源的方式,让 Spring IOC 容器扫描对应的包,从而把 Bean 装配进来。
- 自动装配:通过注解定义,使得一些依赖关系可以通过注解完成。
@Component
@Component(value="user")
public class User{
@Value("1")
private Long id;
@Value("user_name")
private String userName;
................
}
@Component 注解代表 Spring IOC 会把这个类扫描生成 Bean 实例,其中 value 属性的值等同于 XML 方式中的 id,value 值不写 Spring IOC 容器就默认首字母为小写的类名替代。
@Value 代表的是值的注入。
@ComponentScan
public class PojoConfig{
}
这时候需要在同一个包下创建一个 Java Config 告诉 Spring IOC 容器到哪里去扫描对象,@ComponentScan 代表进行扫描,默认是扫描当前包下的路径。它有两个配置选项,第一个是 basePackages,第二个是 basePackageClasses。
@Autowired
在 Spring IOC 容器中,Spring 是先完成 Bean 的定义和生成,然后寻找需要注入的资源,当 Spring 生成所有的 Bean 后,如果发现了这个注解,它就会在 Bean 中查找对应的类型注入。
public interface UserService{
public void UserInfo();
}
@Controller
public class UserController{
@Autowired
private UserService userService;
...................
}
这里我们定义一个 User 的接口,在 Controller 层通过 @Autowired 注解注入,Spring 在扫描到这个注解后会自动寻找对应的类型注入。
有时,IOC 容器会寻找类型失败,默认情况会抛出异常,可以通过 @Autowired(required = false) 将其设置为不一定成功注入,当 IOC 容器没有找到对应的类型时,不会抛出异常。
在少部分情况下,一个接口会有多个实现类,使用 @Autowired 自动装配时可能会出现 IOC 容器不知道使用哪个实现类装配的问题,导致注入失败,原因是 IOC 容器通过类型(by type)获取 Bean,多个实现类导致 Bean 不唯一,可以通过 @Primary(首要注入)注解和 @Qualifier(采用名称查找)注解解决这类问题。