浅谈Spring之DI注解

Spring 在管理 Bean 时会使用到各种注解 ,本文介绍一下开发中常会用到的注解。

以下是常用DI注解比较:

DI 常用注解 说明 用途
@Autowired 自动装配,从ApplicationContext中取出 同类型 的bean装配到被注解项上。 属性 / setter / 构造器
@Qualifier 因为 @Autowired 按照类型自动装配可能存在多个bean实例,可以用 @Qualifier("beanId") 限定 id 筛选出指定的bean。 xml 中也有qualifier 标签。 配合 @AutoWired 使用,限定 id , 但不推荐使用 ,可以直接使用 @Resource 代替。
@Resource 装配资源,默认从ApplicationContext中取出 同名 的bean装配到被注解项上。@Resource 可以通过 byName / byType 两种方式,若不指定默认 byName 匹配装载,找不到按 byType 装载。 属性 / setter
@Required 表示被修饰属性项,在初始化时一定要配置明确值。 setter

@Required

表示被修饰属性项,在初始化时一定要配置明确值。可以用于属性 / setter。

@Autowired

自动装配,从ApplicationContext中取出 同类型 的bean装配到被注解项上。可以用于 属性 / setter / 构造器。

注意事项 :

  • 当没有合适的bean时会抛异常,可以使用 @Autowired(required=false) 避免。

    每个类只有一个构造器可以被标记为 required=true 当有必要属性时推荐用 @Required

  • 可以注解Spring众所周知的解析依赖性接口,即spring自带bean。

    BeanFactory , Applicationcontext , Environment , ResourceLoader , ApplicationEventPublisher , MessageSource 等。

  • @Autowired 不能注解 BeanPostProcessor / BeanFactoryPostProcessor ,可以使用 @Bean 代替。

    因为 @AutowiredBeanPostProcessor 处理,会产生循环依赖。

  • 可以用来装配List/String的Map等集合,如果希望List有序,可以使用 @Order(n) 或使bean实现 Ordered 接口。

@Qualifier

因为 @Autowired 按照类型自动装配可能存在多个bean实例,可以用 @Qualifier("beanId") 限定 id 筛选出指定的bean。 xml 中也有qualifier标签 。配合 @AutoWired 使用,限定 id , 但 不推荐使用 ,可以直接使用 @Resource 代替。

  • @Component 一样,可以用作元注解,自定义限定注解。

  • 即使不使用 @Qualifier 作注解依然可以注册自己的qualifier注解类型。

    1
    2
    3
    4
    5
    6
    7
    8
    <bean id="customAutowireConfigurer" 
    class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
    <property name="customQualifierTypes">
    <set>
    <value>example.CustomQualifier</value>
    </set>
    </property>
    </bean>

@Resource

JSR-250 标准的注解,在 Java EE 5/6 通用,spring同样支持。

装配资源,默认从ApplicationContext中取出 同名 的bean装配到被注解项上。用于属性/只有一个多参数 setter

其实 @Resource 可以通过 byName / byType 两种方式,只是一般使用默认 byName 匹配装载。

注意事项 :

  • 集合/Map类型很多都无法通过类型直接匹配, 即 @Autowired 不可使用。此时可以使用唯一名称 id 进行匹配。

  • 使用 name 属性可以指定被注入bean的名称,默认是属性的名称或setter名称

    之后,会由 ApplicationContext 中的 CommonAnnotationBeanPostProcessor 发现并处理。

    CommonAnnotationBeanPostProcessorApplicationContext 中注册,不仅能识别 JSR-250@Resource ,还支持 Spring2.5 引入的用于初始化回调/销毁回调的 @PostConstruct / @PreDestroy

@Bean

基于java的容器注解,配置和初始化一个由SpringIoc容器管理的新对象的方法,类似于 xml 配置中的 <bean></bean> 。通常配合 @Configuration 使用。

以下的 java 配置xml配置 等效。

1
2
3
4
5
6
7
8
@Configuration
public class AppConfig{

@Bean
public DemoService myService(){
return new DemoServiceImpl();
}
}
1
2
3
<beans>
<bean id="myService" class="org.Demo.Service.MyServiceImpl"/>
</beans>

可以使用 @Scope 注解控制作用域和代理方式。

1
2
3
4
5
6
7
8
9
@Configuration
public class AppConfig{

@Bean(name = "myService", initMethod="init", destroyMethod="cleanup")
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public DemoService myService(){
return new DemoServiceImpl();
}
}

注意事项 :

  • @Bean 的name默认是方法名,也可以使用 @Bean("Demo") 自定义bean名称。

  • 可以使用 @Bean(initMethod="init")@Bean(destroyMethod="cleanup") 指定初始化和销毁bean的方法(一般在return的类中定义相关方法)。

  • 基于泛型的自动装配(//TODO)

    @Bean@Autowired 配合可以实现泛型的自动装配。

@Inject / @Name

Spring3.0 开始支持 JSR330 标准注解(依赖注入注解),其扫描方式与Spring注解一致。

需要以下依赖:

1
2
3
4
5
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
  • @Inject
    • @Inject 等效于 @Autowired ,可以用作类,属性,方法,构造器。
  • @Name
    • 可以表示bean,和 @Component 等效。
    • 可以限制依赖注入的bean名称,和 @Resource 等效。