学习几个非常常用的但是也非常简单的Spring注解。只是做个简单说明,具体可参考Spring官网,说的很详细。
@Primary
其实前面几篇文章已经做过了解了,我们知道Spring自动装配的时候首先是按类型获取候选对象的,那就有可能有多个对象同时满足,这种情况下被@Primary注解标注的Bean会最终被选中并注入。
@Qualifier
有多个候选对象的情况下,还可以使用@Qualifier注解帮助Spring缩小选择范围。
@Qualifier可以和@Autowired配合,作用在属性上或者方法参数上:
public class MovieRecommender {
//作用在属性上
@Autowired
@Qualifier("main")
private MovieCatalog movieCatalog;
// 作用在方法参数上
@Autowired
public void prepare(@Qualifier("main") MovieCatalog movieCatalog,
CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
}
属性或参数名称是默认的Qulifier,不需要显式指定。
@Resource
@Resource是 JSR-250注解(jakarta.annotation.Resource) ,可以作用在属性或者Setter方法上(CommonAnnotationBeanPostProcessor处理)。
@Resource有一个name属性:
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource(name="myMovieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
Spring注入的时候将指定的name作为bean name去容器中查找,不指定name的话Spring默认以@Resource作用的属性名作为bean name查找。
可以通过配置Spring的SimpleJndiBeanFactory以改变Spring的默认行为:通过JNDI查找bean,但是Spring官方建议保持Spring的默认属性、通过bean name匹配。
@Autowired和@Resource的区别
两者都可以用来实现bena的注入,主要区别是依赖注入过程中的查找bean的规则不同。
@Autowire首先是byType + @Qulifier找到所有候选对象,之后如果候选对象比较多的话,通过@Primary过滤,如果没有指定@Primary bean的话,再by name匹配。
@Resource实现通过name查找,匹配不到的话再通过type匹配。
所以两者查找bean的方式不同。
@Value
@Value注解用来将配置文件中指定的数据装配到bean中,可以装配到属性或者方法参数中。
比如:
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("${catalog.name}") String catalog) {
this.catalog = catalog;
}
}
Configation类文件:
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig { }
配置文件application.properties:
catalog.name=MovieCatalog
那么,“MovieCatalog”会注入到方法MovieRecommender的参数catalog中。
默认情况下,如果属性值不存在的话(配置文件中没有配置),属性名会作为值装配进去,不如上述案例如果属性文件不存在的话,catalog=“catalog.name”,其实这种处理方式很不严谨。
可以配置PropertySourcesPlaceholderConfigurer来修改这一默认行为:
@Configuration
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
增加PropertySourcesPlaceholderConfigurer配置之后,配置缺失会导致Spring初始化失败。
@PostConstruct
注解的名字已经能够表达他的功能了,作用在方法上,在Bean被实例化之后调用。
@Resource、 @PostConstruct和 @PreDestroy注解是JAVA6到JAVA8版本的标准功能,但是从JDK9之后开始逐步被移出,到JAVA11已经被彻底移出,迁移到jakarta.annotation中了,所以JAVA基础项目中如果要使用的话需要引入jakarta.annotation-api依赖。