spring学习(九)——spring官方文档阅读(5.0.7)——使用注解配置Spring(@Primary、@Qualifier、支持的JSR250注解)

使用注解配置spring

注解方式和xml方式均可配置spring,注解方式比xml方式先解析,它们满足覆盖原则,因此,对于相同的配置部分,xml方式会覆盖注解方式

使用注解,首先要在xml配置中声明对注解进行处理的类,我们可以用bean定义来声明它们,也可以使用下列方式一次声明所有注解:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

</beans>

声明的注解处理类包括:AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor。

@Required:应用在setter方法下,表示该属性不允许为空,如果为空,容器将会抛出异常

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Required
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // ...
}

@Autowired注解在之前的自动装配章节已经介绍,不在赘述

@Primary:当有多个bean满足匹配结果时,具有@Primary注解的bean将被使用,看一个例子:

@Configuration
public class MovieConfiguration {

    @Bean
    @Primary
    public MovieCatalog firstMovieCatalog() { ... }

    @Bean
    public MovieCatalog secondMovieCatalog() { ... }

    // ...
}
public class MovieRecommender {

    @Autowired
    private MovieCatalog movieCatalog;

    // ...
}


根据类型进行匹配,此时有多个匹配结果,MovieRecommender将选择有@Primary注解的firstMovieCatalog,如果使用xml,可以利用<bean/>的primary属性:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <bean class="example.SimpleMovieCatalog" primary="true">
        <!-- inject any dependencies required by this bean -->
    </bean>

    <bean class="example.SimpleMovieCatalog">
        <!-- inject any dependencies required by this bean -->
    </bean>

    <bean id="movieRecommender" class="example.MovieRecommender"/>

</beans>

@Qualifier:与@Primary不同,@Qualifier的使用更加灵活,通过指定bean的标识符,@Qualifier在有多种匹配结果的情况下,会通过bean的名字进行优先匹配:

public class MovieRecommender {

    @Autowired
    @Qualifier("main")
    private MovieCatalog movieCatalog;

    // ...
}

当有多种匹配结果时,将优先选择标识符为main的bean,@Qualifier也可用于函数参数:

public class MovieRecommender {

    private MovieCatalog movieCatalog;

    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public void prepare(@Qualifier("main")MovieCatalog movieCatalog,
            CustomerPreferenceDao customerPreferenceDao) {
        this.movieCatalog = movieCatalog;
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

在xml中使用qualifier标签表明标识符:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <bean class="example.SimpleMovieCatalog">
        <qualifier value="main"/>

        <!-- inject any dependencies required by this bean -->
    </bean>

    <bean class="example.SimpleMovieCatalog">
        <qualifier value="action"/>

        <!-- inject any dependencies required by this bean -->
    </bean>

    <bean id="movieRecommender" class="example.MovieRecommender"/>

</beans>

@Qualifier也可用于collections,所有标识符相同的bean将被注入,例如Set<MovieCatalog>,其使用注解@Qualifier(“name”),所有标识符为name的bean将被注入,如果没有指定标识符,bean的名字将默认为bean的标识符,如果有多种匹配结果,但是没有@Qualifier、@Primary注解,bean将通过需要依赖的属性名与所有bean的名称(id、name)进行对比,如果bean的名称与属性名相同,将注入这个bean

JSR250的注解介绍

Spring的CommonAnnotationBeanPostProcessor也可以识别JSR250的注解,但是这些注解不包括在Spring包内,在Maven项目中,需要自己添加相应依赖

@Resource:与使用类型匹配的@Autowired不同,@Resource使用名字匹配,@Resource只能用于属性和setter方法上(

@Resource和@Autowired的区别:两者的运行机制不一样,@Resource根据bean的名称直接匹配进行依赖注入,@Autowired先根据类型匹配确定范围,然后根据@qualify配置的标识符或是@primary在范围内进行选择,@Resource只能用于属性、只有一个参数的setter方法,@Autowired允许自我引用(即自己注入自己),当根据类型有多种匹配结果时,自我引用的优先级最低,@Resource根据名称也可能获得bean自己的引用,但是是代理

public class SimpleMovieLister {

    private MovieFinder movieFinder;

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

名为myMovieFinder的Bean将注入

如果我们没有指定name值,那么将会使用默认值,用在属性上,将用属性名进行匹配,用在setter方法上,将用bean的属性的名字进行匹配:

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Resource
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
}

名为movieFinder的bean将匹配

CommonAnnotationBeanPostProcessor将name的值解析为bean的名称,@Resource注解允许注解BeanFactory、ApplicationContext、ResourceLoader、ApplicationEventPublisher、MessageSource接口

public class MovieRecommender {

    @Resource
    private CustomerPreferenceDao customerPreferenceDao;

    @Resource
    private ApplicationContext context;

    public MovieRecommender() {
    }

    // ...
}

上述代码中,首先查找名为customerPreferenceDao的bean,接着进行类型匹配,注入类型为CustomerPreferenceDao的Bean

@PostConstruct:在初始化前先先调用该方法

@PreDestroy:在销毁对象前先调用该方法

public class CachingMovieLister {

    @PostConstruct
    public void populateMovieCache() {
        // populates the movie cache upon initialization...
    }

    @PreDestroy
    public void clearMovieCache() {
        // clears the movie cache upon destruction...
    }
}

猜你喜欢

转载自blog.csdn.net/dhaiuda/article/details/81973920