0%

Bean的装配(二)

@Autowired

基本使用

  • 此注解可以用在Bean的成员变量,setter()方法与构造器上。

  • 默认情况下 (required=true),如果因找不到合适的bean将会导致 autowiring 失败抛出异常,可以通过下面的方式避免:

此成员变量在使用时为 null 值,在这种情况下使用此Bean中的此成员变量时,需要判定其是否为 null ,否则容易出现空指针异常。

1
2
3
4
5
6
7
public class SimpleMovielister {
private MovieFinder movieFinder;

@Autovired(required=false)
public void setMovieFinder(MovieFinder movieFinder){
this,movieFinder = movieFinder;
}
  • 每个类只能有一个构造器被标记为required=true
  • initMethod属性定义初始化前方法,类似于 @PostConstruct
  • destroyMethod属性定义销毁前方法,类似于 @PreDestory
  • @Autovired(required=true),建议使用@Required注解代替

默认可解析的接口

  • 可以使用@Autowired注解那些众所周知的解析依赖性接口,比如:

    • BeanFactory
    • ApplicationContext
    • Environment
    • ResourceLoader
    • ApplicationEventPublisher
    • MessageSource
  • 第二点的意思是,可以在Bean中声明以上接口的引用,再在变量上添加注解,这样这些引用就可以被Spring自动装配


装配集合变量

  • 可以通过添加注解给需要该类型的数组的字段或方法,以提供 ApplicationContext 中的所有特定类型的 bean

例子中 Spring 会加载当前 ApplicationContext 中所有的 Type 为 泛型类型 (MovieCatalog) 的 bean ,及其子类自动装配入 Set (movieCatalogs) 集合;如果泛型类型为接口,那么会自动装配其所有实现类;

1
2
3
4
5
private Set<Moviecatalog> movieCatalogs;
@Autovired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs){
this.movieCatalogs = movieCatalogs;
}
  • 也可以用于装配 Map(String 为 beanId ),List…
1
2
3
4
5
private Map<String,MovleCatalog> movlecatalogs;
@Autovired
publio void setMovieCatalogs(Map<String,MovieCatalog> movieCatalogs){
this.movieCatalogs = movieCatalogs;
}
  • 如果希望数组有序,可以让 bean 实现 org.springframework.core.Ordered 接口或使用的 @Order 注解(Map无效)

  • 注意:@Autowired 由 Spring BeanPostProcessor 处理,故不能在自定义的 BeanPostProcessor 或
    BeanFactoryPostProcessor 类型应用这些注解,这些类型必须通过 XML 或者 Spring 的 @Bean注解加载


@Resource

  • 配合@PostConstruct 定义初始化前方法,类似于 @Autowired 的initMethod属性

  • 配合@PreDestory 定义销毁前方法,类似于 @Autowired 的 destroyMethod属性

  • 以下部分为编辑后转载,点击查看原文

    • @Resource 和 @Autowired 都可以用来装配 bean,都可以用于字段或 setter 方法。
    • @Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false。
    • @Resource默认按名称装配,当找不到与名称匹配的bean时才按照类型进行装配。名称可以通过name属性指定,如果没有指定name属性,当注解写在字段上时,默认取字段名;当注解写在setter方法上时,默认取属性名进行装配。(如果name属性一旦手动指定,就只会按照名称进行装配)
    1
    2
    3
    4
    5
    6
    @Resource(name="cat")
    private Animal animal;
    //等效于
    @Autowired
    @Qualifier("cat")
    private Animal animal;
对比 @Resource @Autowire
注解来源 JDK Spring
装配方式 优先按 name 优先按 type
属性 name、type value,required

@Qualifier & @Named

  • @Named 类似于 @Qualifier

  • 按类型自动装配可能多个 bean 实例的情况,可以使用 Spring 的 @Qualifier 注解缩小范围(或指定唯一),也可以用于指定单独的构造器参数或方法参数

  • 可用于注解集合类型变量

  • 如果通过名字进行注解注入,主要使用的不是 @Autowired (即使在技术上能够通过@Qualifier指定bean的名字),替代方式是使用 JSR-250 @Resource 注解,它是通过其独特的名称来定义来识别特定的目标(这是一个与所声明的类型是无关的匹配过程)

  • 因语义差异,集合或Map类型的bean无法通过@Autowired来注入,因为没有类型匹配到这样的bean,为这些bean使用@Resource注解,通过唯一名称引用集合或Map的bean

@Bean

  • @Bean 标识一个用于配置和初始化一个由 SpringloC 容器管理的新对象的方法,类似于 XML 配置文件的 <bean>
  • 可以在 Spring 的 @Component 注解的类中使用 @Bean 注解任何方法(仅仅是可以),类注解我们通常使用@Configuration 而不是@Component
1
2
3
4
5
6
7
8
@Configuration
publiuc class AppConfig{
@Bean
//这里 Bean的默认name为 myService,即方法名称
public MyService myService(){
return new MyServiceImpl();
}
}

类似于:

1
2
3
<beans>
<bean id="myService" class="com.services.MyserviceImpl "/>
</beans>
  • 默认 @Bean 是单例,可以搭配 @Scope(“scope“)

    ‘scope’ 可以填为 singleton,prototype,request,session,global session