IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring 基于注解的容器配置有哪些? -> 正文阅读

[Java知识库]Spring 基于注解的容器配置有哪些?

目录

1、@Required 注解

2、@Autowired 注解

3、@Primary 注解

4、@Autowired 注解 + @Qualifier 注解

5、同类型 Beans 装配的选择顺序?

6、@Resource 注解

7、@Value 注解

8、@PostConstruct 和 @PreDestroy 注解


// 以下注解都可以往容器中的 Bean 设置属性值,或者定义属性值。

1、@Required 注解

????????用来标识自动装配时必须填充的属性,可以避免空指针,当该属性没有值填充时,容器会抛出异常。//?标识必填属性,5.1 版本中已经被弃用

????????在 Spring 框架 5.1 版本中,@Required 注释和 RequiredAnnotationBeanPostProcessor 已经正式弃用,而支持使用构造函数注入进行必要的设置(或者使用 InitializingBean.afterPropertiesSet() 的自定义实现,或者使用自定义的 @PostConstruct 方法以及 bean 属性的 setter 方法)。

public class SimpleMovieLister {

    private MovieFinder movieFinder;

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

    // ...
}

2、@Autowired 注解

????????JSR 330 的 @Inject 注解可以用来代替 Spring 的 @Autowired 注解。详细内容点击这里

????????从 Spring Framework 4.3 开始,如果目标 bean 一开始只定义了一个构造函数,那么就不再需要在这样的构造函数上使用 @Autowired 注释了。但是,如果有几个可用的构造函数,并且没有默认构造函数,那么必须用 @Autowired 注释其中一个构造函数,以便指示容器使用哪个构造函数?//?@Autowired 标识一个自动装配项,默认通过 bean 的类型进行装配,如果该类型的 bean 有多个,就需要使用一些方法来避免歧义,比如配合 @Primary 注解和?@Qualifier 注解

public class MovieRecommender {

    private final CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    private MovieCatalog movieCatalog;

    @Autowired
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

????????一次性注入多个同类型的 bean?

public class MovieRecommender {

    @Autowired
    private MovieCatalog[] movieCatalogs;

    // ...
}

????????如果希望数组或列表中的 bean 按特定顺序排序,目标 bean 可以实现 org.springframework.core.Ordered 接口,也可以使用 @Order 或标准的 @Priority 注释。否则,beans 的顺序将遵循容器中相应 bean 定义的注册顺序。@Order 值可能会影响注入点的优先级,但它并不会影响单例的启动顺序,单例的启动顺序由依赖关系和 @DependsOn 声明确定。// bean 在容器中的注入顺序可以被定义

????????如果希望自动装备的依赖项为非必须属性(如果依赖项没有可用值,那么使用默认值),可以使用以下方式:

// 方式一:setting the required attribute in @Autowired to false
public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired(required = false)
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // ...
}

// 方式二:通过Java 8的Java.util.optional来表达特定依赖的非必需性质
public class SimpleMovieLister {

    @Autowired
    public void setMovieFinder(Optional<MovieFinder> movieFinder) {
        ...
    }
}

// 方式三:javax.annotation.Nullable from JSR-305
public class SimpleMovieLister {

    @Autowired
    public void setMovieFinder(@Nullable MovieFinder movieFinder) {
        ...
    }
}

????????@Autowired 注解详细的使用,点击这里

????????@Autowired、@Inject、@Value 和 @Resource 注解由 Spring BeanPostProcessor 实现处理。这意味着你不能在自己的 BeanPostProcessor 或 BeanFactoryPostProcessor 类型中应用这些注解。这些类型必须通过 XML 配置或 Spring @Bean 方法显式的进行装配。// 如果自定义后置处理器,那么在自定义的后置处理器中不能使用上述注解

3、@Primary 注解

????????基于类型的自动装配可能会匹配到多个相同类型的 beans,@Primary 用来标注哪个 Bean 被优先选中。// @Primary用于基于类型的自动装配下消除歧义

????????考虑下面的配置,它将 firstMovieCatalog 定义为主要的 MovieCatalog:

@Configuration
public class MovieConfiguration {

    @Bean
    @Primary // firstMovieCatalog 会被优先装配
    public MovieCatalog firstMovieCatalog() { ... }

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

    // ...
}

4、@Autowired 注解 + @Qualifier 注解

????????@Qualifier 注解也是应用在类型匹配上,和 @Autowired 注解配合使用。在 @Qualifier 注解属性中设置值与特定的参数关联起来,可以缩小类型匹配集合,以便为每个参数选择特定的 bean。// Qualifier 限定符,工作流程,通过类型匹配后,再通过名称匹配,它不从语义上表示对唯一 bean id 的引用,相当于一个过滤器。

????????使用示例:

public class MovieRecommender {

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

    // ...
}

或者,对单个参数进行指定
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;
    }

    // ...
}

????????在 Spring 类型匹配中,如果想根据 bean 名称进行匹配,并不需要在 Bean 上显示的配置?@Qualifier 注解。因为当同类型具有多个 bean 候选项时,Spring 会自动根据 Bean 的名称进行匹配。// 类型相同的情况下,自动选择参数名称进行匹配

? ? ? ? 但是,如果只想通过 bean 名称进行匹配,Spring 建议不要使用 @Autowired 注解,应该使用??JSR-250 规范中的 @Resource 注解进行替换。 @Resource 注解定义为通过惟一的名称标识特定的目标组件,目标组件的类型与名称匹配的过程没有关系。而 @Autowired 注解,它具有截然不同的语义:该注解在按类型筛选 beans 之后,会在筛选后的 beans 中再根据限定符中的指定 String 值进行匹配,是一个不断缩小匹配集的过程。// 两种注入方式的区别,@Resource 中名称是唯一的标识符,@Autowired + @Qualifier 中是一次再筛选的过程。

? ? ? ??对于本身被定义为集合、Map 或数组类型的 bean, @Resource 是一个很好的解决方案,它可以通过惟一的名称引用特定的集合或数组类型的 bean。

????????依赖注入中的自我引用注入:

????????自我引用注入就是一个 Bean 自己注入自己的引用。这个是 Spring 中的一个备用方案。自我注入总是在常规组件的依赖注入之后,因此,它不能被设置成 @Primary。在实践中,不是万不得已的场景,应尽量不使用自我注入(例如,通过 bean 的事务代理调用同一实例上的其他方法)。如果有这样的场景,也应该先考虑将受影响的方法分解到单独的 bean 中。

????????在相同的配置类中注入来自 @Bean 方法的结果,实际上也是一个自引用场景。在这种场景下,要么在实际注入该 Bean 的方法签名中配置 Bean 为懒加载属性,要么将受影响的该 @Bean 的方法声明为静态的,将该 Bean 与配置类中的其他实例和其他实例的生命周期进行解耦。

????????@Autowired 注解可以用在字段、构造函数和多参数方法的依赖注入场景中,同时允许在参数级别通过 @Qualifier 注解来缩小匹配集。@Resource 注解只支持字段(域)和单个参数的 setter 方法的注入。所以在构造函数和多参数的方法的依赖注入场景中,只能使用?@Autowired 注解。//?@Autowired 注解拥有更细粒度的注入和更多的适用场景

5、同类型 Beans 装配的选择顺序?

????????The AutowireCandidateResolver 通过以下顺序决定 bean 装配的解析顺序

  1. 解析每个 bean 定义上 autowire-candidate 属性配置的值
  2. 解析 <beans/> 标签中?default-autowire-candidates 配置的值
  3. 解析?@Qualifier 注解和任何注册到?CustomAutowireConfigurer 中的自定义注解?

????????经过上边步骤筛选后,如果仍旧有多个 bean 具备候选资格,那么最终会选择 bean 定义中存在 primary 属性被设置为 true 的 bean 。// 也就是说,@Primary 是被最后解析的

????????CustomAutowireConfigurer 是一个?BeanFactoryPostProcessor ,它允许你注册自定义的 Qualifier 注解,详情请点击这里

<bean id="customAutowireConfigurer"
        class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
    <property name="customQualifierTypes">
        <set>
            <value>example.CustomQualifier</value>
        </set>
    </property>
</bean>

6、@Resource 注解

?????????@Resource 是 Java JSR-250 规范中的注解,Spring 也同样支持。@Resource 通过指定 bean 名称进行依赖注入。如果?@Resource 没有显示的配置 bean 名称,那么该注解与?@Autowired 注解一样,会先通过 bean 的类型进行匹配。对于已知的 bean,比如:BeanFactory,ApplicationContext,ResourceLoader,ApplicationEventPublisher 等同样也可以使用 @Resource 进行自动装备。

public class MovieRecommender {

    @Resource
    private CustomerPreferenceDao customerPreferenceDao;

    @Resource
    private ApplicationContext context; 

    public MovieRecommender() {
    }

    // ...
}

7、@Value 注解

????????(1)@Value 注解用来注入一些被外部化的属性:

@Component
public class MovieRecommender {

    private final String catalog;

    public MovieRecommender(@Value("${catalog.name}") String catalog) {
        this.catalog = catalog;
    }
}

????????(2)指定需要解析的外部配置文件:

@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig { }

????????(3)外部配置文件 application.properties 内容:

catalog.name=MovieCatalog

????????在上边步骤下,catalog 参数的值将被赋值为:MovieCatalog。

? ? ? ? 其中,如果 ${} 占位符无法被解析,将导致 Spring 初始化失败, 另外,占位符也可以使用? PlaceholderConfigurerSupport 中的 setPlaceholderPrefix()、setPlaceholderSuffix() 或 setValueSeparator() 等方法来实现自定义。

? ? ? ? 注意:Spring Boot 默认配置了一个?PropertySourcesPlaceholderConfigurer bean,该 bean 默认会从 application.properties 和 application.yml 文件中读取 properties 属性

????????Spring 提供的内置转换器支持自动处理简单的类型转换(例如 Integer 或 int )。在 @Value 注入的值中,如果有使用多个逗号分隔的值可以自动转换为 String 数组,无需额外的处理。// 简单类型自动转换

? ? ? ? 在 @Value 注解中使用冒号,可以为注解配置默认值,下边示例将展示了在 @Value 注解中,catalog.name 的默认值为?defaultCatalog:

@Component
public class MovieRecommender {

    private final String catalog;

    public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) {
        this.catalog = catalog;
    }
}

????????Spring BeanPostProcessor 在后台使用 ConversionService 来处理 @Value 中将 String 值转换为目标类型的过程。如果你想支持自定义类型转换,可以自定义 ConversionService bean 的实例,如下例所示:// 自定义类型处理

@Configuration
public class AppConfig {

    @Bean
    public ConversionService conversionService() {
        DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
        conversionService.addConverter(new MyCustomConverter());
        return conversionService;
    }
}

????????在?@Value 中使用更多的?SpEL 表达式,更多细节点击这里

8、@PostConstruct 和 @PreDestroy 注解

????????CommonAnnotationBeanPostProcessor 不仅可以识别 @Resource 注解,还可以识别 JSR-250 中的生命周期注解:javax.annotation.PostConstruct 和 javax.annotation.PreDestroy 。@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...
    }
}

????????注意:跟 @Resource 注解一样,@PostConstruct 和 @PreDestroy 注解也是 JDK 6 到 8 标准Java 库的一部分。然而,在 JDK 9 中,整个 javax.annotation 包从 Java 核心模块中被分离出来,最终在 JDK 11 中被移除。因此,如果在 JDK 9 以上版本中要继续使用上述注解,需要通过 Maven Central 获得 javax.annotation-api 的依赖。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:12:25  更:2022-11-05 00:14:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 -2025/3/10 18:21:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码