使用 JSR-250 中的 @Resource 和 @Qualifier 注解
如果希望根据 name 执行自动装配,那么应该使用 JSR-250 提供的 @Resource 注解,而不应该使用 @Autowired 与 @Qualifier 的组合。
@Resource 使用 byName 的方式执行自动封装。@Resource 标注可以作用于带一个参数的 Setter 方法、字段,以及带一个参数的普通方法上。@Resource 注解有一个 name 属性,用于指定 Bean 在配置文件中对应的名字。如果没有指定 name 属性,那么默认值就是字段或者属性的名字。@Resource 和 @Qualifier 的配合虽然仍然成立,但是 @Qualifier 对于 @Resource 而言,几乎与 name 属性等效。
如果 @Resource 没有指定 name 属性,那么使用 byName 匹配失败后,会退而使用 byType 继续匹配,如果再失败,则抛出异常。在没有为 @Resource 注解显式指定 name 属性的前提下,如果将其标注在 BeanFactory 类型、ApplicationContext 类型、ResourceLoader 类型、ApplicationEventPublisher 类型、MessageSource 类型上,那么 Spring 会自动注入这些实现类的实例,不需要额外的操作。此时
name 属性不需要指定 ( 或者指定为""),否则注入失败;如果使用了 @Qualifier,则该注解将被忽略。而对于用户自定义类型的注入,@Qualifier 和 name 等价,并且不被忽略。
的 primary 和 autowire-candidate 属性对 @Resource、@Autowired 仍然有效。
使用 @Configuration 和 @Bean 进行 Bean 的声明
虽然 2.0 版本发布以来,Spring 陆续提供了十多个注解,但是提供的这些注解只是为了在某些情况下简化 XML 的配置,并非要取代 XML 配置方式。这一点可以从 Spring IoC 容器的初始化类可以看出:ApplicationContext 接口的最常用的实现类是 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext,以及面向 Portlet 的 XmlPortletApplicationContext 和面向 web
的 XmlWebApplicationContext,它们都是面向 XML 的。Spring 3.0 新增了另外两个实现类:AnnotationConfigApplicationContext 和 AnnotationConfigWebApplicationContext。从名字便可以看出,它们是为注解而生,直接依赖于注解作为容器配置信息来源的 IoC 容器初始化类。由于 AnnotationConfigWebApplicationContext 是 AnnotationConfigApplicationContext
的 web 版本,其用法与后者相比几乎没有什么差别,因此本文将以 AnnotationConfigApplicationContext 为例进行讲解。
AnnotationConfigApplicationContext 搭配上 @Configuration 和 @Bean 注解,自此,XML 配置方式不再是 Spring IoC 容器的唯一配置方式。两者在一定范围内存在着竞争的关系,但是它们在大多数情况下还是相互协作的关系,两者的结合使得 Spring IoC 容器的配置更简单,更强大。
之前,我们将配置信息集中写在 XML 中,如今使用注解,配置信息的载体由 XML 文件转移到了 Java 类中。我们通常将用于存放配置信息的类的类名以 “Config” 结尾,比如 AppDaoConfig.java、AppServiceConfig.java 等等。我们需要在用于指定配置信息的类上加上 @Configuration 注解,以明确指出该类是 Bean 配置的信息源。并且 Spring 对标注 Configuration 的类有如下要求:
♦ 配置类不能是 final 的;
♦ 配置类不能是本地化的,亦即不能将配置类定义在其他类的方法内部;
♦ 配置类必须有一个无参构造函数。
AnnotationConfigApplicationContext 将配置类中标注了 @Bean 的方法的返回值识别为 Spring Bean,并注册到容器中,受 IoC 容器管理。@Bean 的作用等价于 XML 配置中的 标签。示例如下:
- @Configuration
-
publicclassBookStoreDaoConfig{
-
@Bean
-
publicUserDaouserDao(){returnnewUserDaoImpl();}
-
@Bean
-
publicBookDaobookDao(){returnnewBookDaoImpl();}
- }
Spring 在解析到以上文件时,将识别出标注 @Bean 的所有方法,执行之,并将方法的返回值 ( 这里是 UserDaoImpl 和 BookDaoImpl 对象 ) 注册到 IoC 容器中。默认情况下,Bean 的名字即为方法名。因此,与以上配置等价的 XML 配置如下:
- <beanid=”userDao”class=”bookstore.dao.UserDaoImpl”/>
-
<beanid=”bookDao”class=”bookstore.dao.BookDaoImpl”/>
@Bean 具有以下四个属性:
♦ name -- 指定一个或者多个 Bean 的名字。这等价于 XML 配置中 的 name 属性。
♦ initMethod -- 容器在初始化完 Bean 之后,会调用该属性指定的方法。这等价于 XML 配置中 的 init-method 属性。
♦ destroyMethod -- 该属性与 initMethod 功能相似,在容器销毁 Bean 之前,会调用该属性指定的方法。这等价于 XML 配置中 的 destroy-method 属性。
♦ autowire -- 指定 Bean 属性的自动装配策略,取值是 Autowire 类型的三个静态属性。Autowire.BY_NAME,Autowire.BY_TYPE,Autowire.NO。与 XML 配置中的 autowire 属性的取值相比,这里少了 constructor,这是因为 constructor 在这里已经没有意义了。
@Bean 没有直接提供指定作用域的属性,可以通过 @Scope 来实现该功能,关于 @Scope 的用法已在上文列举。
下面讲解基于注解的容器初始化。AnnotationConfigApplicationContext 提供了三个构造函数用于初始化容器。
♦ AnnotationConfigApplicationContext():该构造函数初始化一个空容器,容器不包含任何 Bean 信息,需要在稍后通过调用其 register() 方法注册配置类,并调用 refresh() 方法刷新容器。
♦ AnnotationConfigApplicationContext(Class... annotatedClasses):这是最常用的构造函数,通过将涉及到的配置类传递给该构造函数,以实现将相应配置类中的 Bean 自动注册到容器中。
♦ AnnotationConfigApplicationContext(String... basePackages):该构造函数会自动扫描以给定的包及其子包下的所有类,并自动识别所有的 Spring Bean,将其注册到容器中。它不但识别标注 @Configuration 的配置类并正确解析,而且同样能识别使用 @Repository、@Service、@Controller、@Component 标注的类。
除了使用上面第三种类型的构造函数让容器自动扫描 Bean 的配置信息以外,AnnotationConfigApplicationContext 还提供了 scan() 方法,其功能与上面也类似,该方法主要用在容器初始化之后动态增加 Bean 至容器中。调用了该方法以后,通常需要立即手动调用 refresh() 刷新容器,以让变更立即生效。
需要注意的是,AnnotationConfigApplicationContext 在解析配置类时,会将配置类自身注册为一个 Bean,因为 @Configuration 注解本身定义时被 @Component 标注了。因此可以说,一个 @Configuration 同时也是一个 @Component。大多数情况下,开发者用不到该 Bean,并且在理想情况下,该 Bean 应该是对开发者透明的。@Configuration 的定义如下所示:
- @Target({ElementType.TYPE})
-
@Retention(RetentionPolicy.RUNTIME)
-
@Documented
-
@Component
-
public@interfaceConfiguration{
-
Stringvalue()default"";
- }
在一般的项目中,为了结构清晰,通常会根据软件的模块或者结构定义多个 XML 配置文件,然后再定义一个入口的配置文件,该文件使用 将其他的配置文件组织起来。最后只需将该文件传给 ClassPathXmlApplicationContext 的构造函数即可。针对基于注解的配置,Spring 也提供了类似的功能,只需定义一个入口配置类,并在该类上使用 @Import 注解引入其他的配置类即可,最后只需要将该入口类传递给 AnnotationConfigApplicationContext。具体示例如下:
- @Configuration
-
@Import({BookStoreServiceConfig.class,BookStoreDaoConfig.class})
-
publicclassBookStoreConfig{…}
混合使用 XML 与注解进行 Bean 的配置
设计 @Configuration 和 @Bean 的初衷,并不是为了完全取代 XML,而是为了在 XML 之外多一种可行的选择。由于 Spring 自发布以来,Spring 开发小组便不断简化 XML 配置,使得 XML 配置方式已经非常成熟,加上 Spring 2.0 以后出现了一系列命名空间的支持,使得 XML 配置方式成为了使用简单、功能强大的 Bean 定义方式。而且,XML 配置的一些高级功能目前还没有相关注解能够直接支持。因此,在目前的多数项目中,要么使用纯粹的 XML 配置方式进行 Bean
的配置,要么使用以注解为主,XML 为辅的配置方式进行 Bean 的配置。
之所以会出现两者共存的情况,主要归结为三个原因:其一,目前绝大多数采用 Spring 进行开发的项目,几乎都是基于 XML 配置方式的,Spring 在引入注解的同时,必须保证注解能够与 XML 和谐共存,这是前提;其二,由于注解引入较晚,因此功能也没有发展多年的 XML 强大,因此,对于复杂的配置,注解还很难独当一面,在一段时间内仍然需要 XML 的配合才能解决问题。除此之外,Spring 的 Bean 的配置方式与 Spring 核心模块之间是解耦的,因此,改变配置方式对 Spring 的框架自身是透明的。Spring
可以通过使用 Bean 后处理器 (BeanPostProcessor) 非常方便的增加对于注解的支持。这在技术实现上非常容易的事情。
要使用混合配置方式,首先需要判断以哪一种配置方式为主。对这个问题的不同回答将会直接影响到实现的方式。然而大可不必为此伤脑筋,因为不论是以 XML 为主,还是以注解为主,配置方式都是简单而且容易理解的。这里不存在错误的决定,因为仅仅是表现方式不一样。我们首先假设以 XML 配置为主的情况。
对于已经存在的大型项目,可能初期是以 XML 进行 Bean 配置的,后续逐渐加入了注解的支持,这时我们只需在 XML 配置文件中将被 @Configuration 标注的类定义为普通的 ,同时注册处理注解的 Bean 后处理器即可。示例如下:
// 假设存在如下的 @Configuration 类:
- packagebookstore.config;
-
importbookstore.dao.*;
-
@Configuration
-
publicclassMyConfig{
-
@Bean
-
publicUserDaouserDao(){
-
returnnewUserDaoImpl();
- }
- }
此时,只需在 XML 中作如下声明即可:
- <beans…>
- ……
-
<context:annotation-config/>
-
<beanclass=”demo.config.MyConfig”/>
-
beans>
由于启用了针对注解的 Bean 后处理器,因此在 ApplicationContext 解析到 MyConfig 类时,会发现该类标注了 @Configuration 注解,随后便会处理该类中标注 @Bean 的方法,将这些方法的返回值注册为容器总的 Bean。
对于以上的方式,如果存在多个标注了 @Configuration 的类,则需要在 XML 文件中逐一列出。另一种方式是使用前面提到的自动扫描功能,配置如下:
- <context:component-scanbase-package=”bookstore.config”/>
如此,Spring 将扫描所有 demo.config 包及其子包中的类,识别所有标记了 @Component、@Controller、@Service、@Repository 注解的类,由于 @Configuration 注解本身也用 @Component 标注了,Spring 将能够识别出 @Configuration 标注类并正确解析之。
对于以注解为中心的配置方式,只需使用 @ImportResource 注解引入存在的 XML 即可,如下所示:
- @Configuration
-
@ImportResource(“classpath:/bookstore/config/spring-beans.xml”)
-
publicclassMyConfig{
- ……
- }
// 容器的初始化过程和纯粹的以配置为中心的方式一致:
- AnnotationConfigApplicationContextctx=
-
newAnnotationConfigApplicationContext(MyConfig.class);
- ……
结束语
从 2.0 版本开始,Spring 的每一次更新都会提供更多新的注解供开发者使用。这满足了注解爱好者的胃口。但是正如前面所说,Spring 提供更多的注解并不是为了有朝一日取代 XML 配置方式,而是为了给开发者多一种选择。两种声明 Bean 的方式各有特色,XML 方式更加灵活,并且发展的相对成熟,这种配置方式为大多数 Spring 开发者熟悉;注解方式使用起来非常简洁,但是尚处于发展阶段。我们很难说两种配置方式孰优孰劣,但是如果能够灵活搭配两种方式,一定能够进一步提升开发效率。
分享到:
相关推荐
数分1.11Tableau安装及使用教程
内容概要:本文主要围绕着计算机信息系统运行管理员考试展开讨论,详细介绍了有关信息系统在运维中的各种问题及其应对方案。具体而言,文中不仅列举出了不同类型的信息系统对其本身的要求,而且还深入探讨了运维管理中面临的挑战和技术手段。另外,文章特别提及了一些特定类型的系统(例如政府系统和财务管理等),并指明在面对它们时需要考虑的安全级别、稳定性等关键要素;同时也强调了良好的文档管理和合理的设施运维对象划分,以及软硬件的选择与维护。同时文章还讲解了多种工具的作用(比如Nagios),以及硬件如计算机机房和UPS的具体规格和要求;并且讲述了关于变更管理和发布管理等的概念与实际应用场景。此外,在最后一部分内容里也谈到了云架构及其各个构成部分。 适用人群:本文适合即将参加软考信息运行管理员认证的专业人士,也适用于希望深入了解信息系统运作、管理和维护的技术从业者和相关领域的管理人员。 使用场景及目标:本资料旨在辅助考生掌握信息系统的高效、稳健地构建与运营所需的知识和技术,帮助他们顺利通过软考的同时提升实战经验;同时也为企业信息化建设提供了宝贵的理论基础和实践指南。 其他说明:虽然本文聚焦于特定职业资格证书
大型语言模型(LLMs)的出现彻底改变了自然语言处理。然而,这些模型在从大量数据集中检索精确信息时面临挑战。检索增强生成(RAG)旨在通过结合外部信息检索系统来增强LLMs,从而提高响应的准确性和上下文性。尽管有所改进,RAG在高容量、低信息密度数据库中的全面检索仍然存在困难,并且缺乏关系意识,导致答案碎片化。 为了解决这一问题,本文介绍了伪知识图谱(PKG)框架,该框架通过集成元路径检索、图内文本和向量检索到LLMs中,旨在克服这些限制。通过保留自然语言文本并利用各种检索技术,PKG提供了更丰富的知识表示并提高了信息检索的准确性。使用Open Compass和MultiHop-RAG基准进行的广泛评估表明,该框架在管理和处理大量数据及复杂关系方面具有有效性。
python学习教程
请到网盘中自取压缩包,此包为kibana-7.10.2 镜像压缩包,是通过现有镜像导出来的,主要是为了解决有些机器无法连接外网,导致无法下载镜像 加载镜像: docker load -i kibana-7.10.2.tar 查看镜像: docker images 备注:elk此镜像配套资源,相同版本的elasticsearch和logstash,请在我的资源中搜索其他镜像
UniApp开发一个简单的记事本应用文字教程
基于Andorid的音乐播放器项目设计(QQ音乐)实现源码,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。
python学习资源
React Developer Tools在谷歌拓展的应用商城下载不了任何解决
【毕业设计-java】springboot-vue健身房管理系统源码(完整前后端+mysql+说明文档+LunW).zip
python学习资源
本文提供了一套完整的指南,帮助用户在Anaconda中配置PyTorch环境,便于深度学习开发。首先,用户需要确保安装Anaconda,并通过Anaconda Prompt创建一个新的虚拟环境,以隔离项目依赖。创建好环境后,用户可以根据所用操作系统以及CUDA版本,选择适合的安装命令。对于Windows和Linux用户,提供了安装PyTorch、TorchVision和TorchAudio的具体命令,包括CUDA Toolkit的版本选择。macOS用户则可以安装仅支持CPU的版本。安装完成后,通过简单的Python代码验证PyTorch是否成功安装以及GPU的可用性。文中还列出了常见问题及解决方法,帮助用户快速排查安装过程中可能遇到的障碍。通过遵循这些步骤,用户可以顺利搭建起一个专属的PyTorch开发环境,提升深度学习的工作效率和体验。
python学习教程
内容概要:本文汇总了学习数据结构的相关资源,旨在帮助读者系统化地理解和掌握这一计算机科学的基础概念。文中首先列举了一系列权威在线学习资源,包括知名教授的主页、在线编程平台LeetCode和技术博客,这些资源不仅理论丰富,还提供大量的实例和练习机会。接着推荐了几本经典的书籍,如《算法导论》、《大话数据结构》,适合不同程度的学习者深入理解算法和数据结构的细节。此外,还特别提及了几门高质量的网络课程,能够为初学者提供清晰的学习路径。最后强调通过动手实践,如动态数组的C语言实现以及算法题目的刷题练习,是提高编程技能的有效途径。 适合人群:对于想要系统学习并掌握数据结构的程序员及爱好者。 使用场景及目标:适用于个人自学或者课堂教学,目的是通过综合使用理论学习、实践操作来达到对数据结构和算法有全面深刻的认识。 其他说明:本文提供了丰富的链接,让读者可以直接访问各个优质教育资源进行深度探究,鼓励大家积极参与讨论,相互分享心得体验,形成良好的互动交流氛围。
QMI8658 Datasheet
【毕业设计】java-springboot-vue火车订票管理系统源码(完整前后端+mysql+说明文档+LunW).zip
Screenshot_2025-03-10-22-52-22-034_com.miui.notes.jpg
python学习教程
基于unet医学细胞分割python实战源码+数据集(图像分割大作业).zip 【项目简介】 该项目是一个基于 U-Net 的医学细胞分割实战项目,适合初学者学习。项目包含了数据集准备、模型构建、训练和验证等完整的流程。 主要功能 实现 U-Net 模型的构建和训练 提供医学细胞分割的数据集和数据预处理 实现分割模型的评估指标,如 Dice 系数等 Python PyTorch U-Net 模型 【项目说明】 1.多数小白下载后,在使用过程,可能会遇到些小问题,若自己解决不了,请及时私信描述你的问题,我会第一时间提供帮助,也可以远程指导 2.项目代码完整可靠,但难度适中,满足一些毕设、课设要求,且属于易上手的优质项目,项目内基本都有说明文档,按照操作即可,遇到困难也可私信交流 3.适用人群:各大计算机相关专业行业的在校学生、高校老师、公司程序员等下载使用