Spring FrameWork从入门到NB -@primary、@Qualifier、@Resource&@Value

学习几个非常常用的但是也非常简单的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依赖。

上一篇 Spring FrameWork从入门到NB -基于注解配置 & @Autowired注解

你可能感兴趣的:(javaspring)