Spring 中的自动装配,如果遇到多个实例如何处理?

2,904 total views, 3 views today

标记了@Autowired 注解的字段/方法,会由 Spring 容器自动的赋值一个实例化的对象。@Autowired 总是采用 byType 的方式实现自动装配,只要找到需要装配的类型的实例就行了。有时候 Spring 容器中,同一个类型的实例有多个,那么可能会出现异常,这个时候就需要精确的自动装配,需要用到@Qualifier 注解。

示例

有 2 个类,User 和 Company。

上面的代码中,User 类中有一个 company 字段,标注了 Autowired,这就说明 Spring 容器中的 User 对象,company 的自动的值会被自动赋值,不会是 null。

配置类,定义自动扫描的路径。

Main 入口。

运行后输出:
init Company…
init user…
CompanyCode:475779800
可以看到 User 类中的 company 字段并未主动初始化,但是却有值。

如果有 2 个 Bean 实例

上面的例子改一下

这时候,Spring 容器中出现了 2 个 Company 的实例,一个是自动扫描得到的,另一个是配置类中配置的。此时,Autowired 会将属性的名称作为组件的 id 去容器中查找,即用 company 作为实例的 id 去匹配实例,那么就又会匹配到自动扫描后生成的那个实例,因为那个实例的名字就是首字母小写的类名 company。

如果必须要以配置类中的实例为优先实例,那么只要在该实例上标注上@Primary 注解,表示默认首先该实例。

注意,采用@Primary 后,此实例会优先加载,Main 方法运行后,得到的 companyCode 是 99999:
init Company…
init user…
init Company…
CompanyCode:99999

当然,也可以更直接的,指定自动绑定的实例。上面的 User 类,修改如下代码:

那么 company 注入的时候,会去找 id 为 getCompany 的实例,也就是会找到配置类中配置的实例。

 

总结

@Autowired 根据类型自动注入对象的实例,如果同一个类型的实例有多个,则会根据实例的 id 名去匹配,但这种不是最好的方式,建议直接用@Qualifier 注解指定需要注入的实例,或者用@Primary 注解标识出首选 Bean,减少不必要的干扰。

原创文章,转载请注明出处!http://www.javathings.top/spring中的自动装配,如果遇到多个实例如何处理?/

About: wusq


发表评论

邮箱地址不会被公开。 必填项已用*标注