编程技术分享平台

网站首页 > 技术教程 正文

spring核心技术之三:Annotation容器配置

xnh888 2024-10-19 16:00:15 技术教程 15 ℃ 0 评论

思考:基于注解的容器配置方式比传统xml方式更好么?

答:其实每一种方式都有利有弊,开发者选择他们喜欢的合适的方式就可以了。注解方式特点简单明了,但bean配置分散,难以总体控制;而xml方式使业务组件与源码分离,更有利于总体控制所配置的bean元数据。实际项目中往往根据需要都是上面两种方式结合使用。

思考:注解工作原理是如何进行的呢?

答:Spring实现自动装配,继承了org.springframework.web.context.support.SpringBeanAutowiringSupport类,该类定义了无参构造函数:

public SpringBeanAutowiringSupport() {
 processInjectionBasedOnCurrentContext(this);
 }

而Java实例构造时会调用默认父类无参构造方法,Spring正是利用了这一点,让"操作元素的代码"得以自动执行,最终注入还是利用了Java反射机制来实现bean自动注入的,如下图:

下面介绍几个常用的类内部注解。

  • @Required

用于bean中setter方法,保证下面movieFinder不为空,如下:

public class SimpleMovieLister {
 private MovieFinder movieFinder;
 @Required //set方法
 public void setMovieFinder(MovieFinder movieFinder) {
 this.movieFinder = movieFinder;
 }
 // ...
}

该注解表明在bean配置时间内,配置的属性值必须注入,否则抛出BeanInitializationException异常,我们可以通过xml文件的bean中明确指定属性,或者通过自动注入注解方式来保证属性值不为空。

  • @Autowired

可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作,如下

public class MovieRecommender {
 private final CustomerPreferenceDao customerPreferenceDao;
 @Autowired //成员变量
 private MovieCatalog movieCatalog;
 @Autowired //构造函数
 public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
 this.customerPreferenceDao = customerPreferenceDao;
 }
	@Autowired //普通方法
 public void prepare(MovieCatalog movieCatalog) {
 this.movieCatalog = movieCatalog;
 
 }
}

注意事项:

在使用@Autowired时,首先查询对应类型的bean,如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据,如果查询的结果不止一个,那么@Autowired会根据名称来查找,如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false,如下

public class SimpleMovieLister {
 private MovieFinder movieFinder;
 @Autowired(required = false) //保证为空,不抛异常
 public void setMovieFinder(MovieFinder movieFinder) {
 this.movieFinder = movieFinder;
 }
.
}

Spring 5.0以后,可以用@Nullable来解决异常问题,如下:

public class SimpleMovieLister {
 @Autowired
 public void setMovieFinder(@Nullable MovieFinder movieFinder) {
 ...
 }
}
  • @Primary

IOC根据类型注解可能会有多个对应的bean,如下:

public class MovieRecommender {
 @Autowired
 private MovieCatalog movieCatalog;
 // ...
}

可通过@Primary则指定满足条件具有优先权的bean。如下:

 @Configuration
public class MovieConfiguration {
 @Bean
 @Primary //具有优先权
 public MovieCatalog firstMovieCatalog() { ... }
 @Bean
 public MovieCatalog secondMovieCatalog() { ... }
 // ...
}

则MovieRecommender用firstMovieCatalo来注入。

  • @Qualifier

当类型注解可能会有多个对应的bean,如何选择正确的bean的方法,比@Primary更灵活,可以通过@Qualifier指定值来选择哪个是你需要的bean。如下:

 @Configuration
public class MovieConfiguration {
 @Bean("first")
 public MovieCatalog firstMovieCatalog() { ... }
 @Bean("sec") //根据名称指定
 public MovieCatalog secondMovieCatalog() { ... }
 // ...
}

加上@Qualifier(“sec”)就知道IOC控制器就知道要注入哪个bean

public class MovieRecommender {
	@Autowired
	@Qualifier("sec")
 private MovieCatalog movieCatalog;
 // ...
}
  • @Resource

是Java注入JSR-250提供的注解方式,spring 也提供了支持。Spring通过其带有的name属性来实现注入。如下

public class SimpleMovieLister {
 private MovieFinder movieFinder;
 @Resource(name="myMovieFinder") 
 public void setMovieFinder(MovieFinder movieFinder) {
 this.movieFinder = movieFinder;
 }
}

如果@Resource不带name,则默认值是bean属性名称。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表