Spring IoC容器(三)注解

 Spring 除了支持通过XML形式配置Bean外,也支持通过注解的形式来配置Bean。需要简洁、易于维护和低耦合度场景下,注解是更好的选择;需要可读性强、可扩展性和分离关注点的场景下,XML是一个更好的选择。

方式

优点

缺点

注解

  1. 简洁易读:注解的名称和含义都比较直观,易于理解。
  2. 易于维护:当需要修改配置时,只需要修改相应的注解即可,不需要像XML那样要修改多个文件。
  3. 降低耦合度:通过自动布线(Autowired)可以减少代码之间的硬编码依赖,降低耦合度。
  1. 可能会破坏类的纯洁性:使用注解可能会将一些业务逻辑和配置逻辑混在一起,破坏类的纯洁性。
  2. 不易调试:当出现配置错误时,可能很难定位问题所在,因为配置信息都隐藏在注解中。

xml

  1. 易于阅读和编辑,可读性强:XML格式的配置文件结构清晰,易于阅读和编辑。可以更好地分离关注点,使得代码更加清晰易读。
  2. 可扩展性强:XML配置文件可以方便地扩展和定制化,满足不同的项目需求。
  1. 维护成本高:通常比注解方式更加复杂,需要更多维护成本。
  2. 代码耦合度高:需要硬编码配置信息,使得代码之间耦合度较高。
  3. 不够简洁:需要更多的文件和代码量。

表 注解与xml 形式配置Bean的优缺点

1 常用注解

1.1 @Configuration

是Spring中一个核心注解,用于应用程序的配置信息(类似于xml配置文件)。作用于类,被注解的类里面可以配置和管理Bean。AnnotationConfigApplicationContext可用来创建支持注解的上下文。其接受一个@Configuration注解的类型,在创建上下文时,其注解的类会被容器创建实例。被创建的实例可以像其他bean一样被容器管理及获取。

1.1.1 @ComponentScan

用于定位扫描Bean的位置。@ComponentScan(basePackages = "beans") 表示扫描beans包下的所有Bean。与@Configuration配合一起使用时,beans包下所有有注解Bean的类都会被容器注册为bean。

1.2 @Autowired、@Resource与@Inject

这三个注解功能类似,都是用于自动装配Bean。但是在Spring 5.1之后@Autowired 与 @Resource被废弃了,可以使用@Inject来代替。

 1.2.1 @Autowired

@Autowired 用于自动装配bean,有以下作用:

  1. 自动装配,当一个类中声明了@Autowired,Spring容器会自动寻找匹配(或创建)的Bean并注入到该类中。这大大简化了Bean的装配过程。
  2. 配置灵活,可标注在成员变量、方法或构造函数上。
  3. 可根据类型、字段名称(与bean的类型名称小写做匹配)及名称自动匹配(名称需要配合@Qualifier一起使用)。

还可以对集合类型及Map进行自动装配。把容器中符合的类型实例注入到集合中,或者将bean名作为key,bean实例作为value注入到Map中。

对于有多种同类型的Bean,如果使用@Autowired的字段名在这些bean中匹配不上,则会报错,这时可以在配置bean的地方,对其中一个bean加上@Primary 用来指定该类型的一个首要的bean。

public interface Mapper {
}@Repository
public class OrderMapper implements Mapper{public OrderMapper() {System.out.println("OrderMapper实例化");}
}@Repository
public class UserMapper implements Mapper{public UserMapper() {System.out.println("UserMapper实例化");}
}@Service
public class OrderService {public OrderService() {System.out.println("实例化");}@Autowiredprivate Mapper userMapper;@Autowiredprivate Mapper orderMapper;@Autowiredprivate List<Mapper> mappers;@Autowiredprivate Map<String,Mapper> mapperMap;public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);OrderService service = context.getBean(OrderService.class);System.out.println(service);}@Overridepublic String toString() {return "OrderService{" +"userMapper=" + userMapper +", orderMapper=" + orderMapper +", mappers=" + mappers +", mapperMap=" + mapperMap +'}';}
}@Configuration
@ComponentScan(basePackages = "beans")
public class SpringConfig {public SpringConfig() {System.out.println("SpringConfig实例化");}
}

1.2.2 @Qualifier

用于解决自动装配时的歧义问题,可以帮助指定要注入的确切Bean。可以用来指定Bean的名称及类型。注意:使用@Qualifier 指定类型时,必须确保所指定的类型是唯一的,否则仍会抛出异常。

public interface MyService {
}@Configuration
@ComponentScan(basePackages = "beans.qualifier")
public class MyConfig {@Bean@Qualifier("service1")public MyService myService1() {return new MyService() {};}@Bean@Qualifier("service2")public MyService myService2() {return new MyService() {};}}@Controller
public class MyController {@Autowired@Qualifier("service1")private MyService service1;@Autowired@Qualifier("service2")private MyService service2;public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);System.out.println(context.getBean(MyController.class));}@Overridepublic String toString() {return "MyController{" +"service1=" + service1 +", service2=" + service2 +'}';}
}

1.2.3 @Autowired 被废弃的原因

1)保持与Java规范的一致性。@Autowired是Spring特有的注解,而@Inject是Java规范中的注解。(@Resource 被废弃也是因为这个原因,其是Java EE规范和Spring的一个注解,不是Java规范的注解)

2)处理多个匹配的依赖项时,如果没有明确指定依赖名称,Spring会抛出异常,这可能会导致代码的不稳定性。

3)类的成员变量如果使用了@Autowired,这个类必须交给Spring管理,否则该注解就会失效。

1.3 被废弃的注解

JSR 是Java依赖注入标准的规范,它提供了一种标准的依赖注入机制。其中有些注解可以代替Spring的某些注解。JSR-330中,像@Autowired 一样,有些注解已被Spring废弃,用JSR-330的注解代替(需要引入javax.inject包)。

Spring

JSR-330

@Autowired

@Inject

@Component

@Names/@ManagedBean

@Scope(“singleton”)

@Singleton

@Qualifier

@Qualifier/@Named

@Required

无,但是该注解在Spring 5.1后被废弃,Spring 5.1 引入构造函数注入和自定义InitializingBean接口来实现初始化逻辑来替换这个注解。

表 JSR330 可替换 Spring中的注解

2 @ComponentScan组件扫描

用于指定Spring在哪些包中搜索被@Component(报告@Service、@Controller等)注解的类,并将它们自动注册为Spring容器中的Bean。还可以指定一些属性来自定义扫描行为:

basePackages/value

要扫描的包名,接受字符串数组类型。

basePackageClasses

要扫描的包中的一个类,将扫描该类所在包及其子包。

includeFilters

用于指定只包含满足特定条件的组件。是一个Filter类型数组,每个Filter对象包含type、classes属性和pattern属性等,classes属性是一个包含需要过滤的类的数组。pattern是指定匹配的正则表达式。

excludeFilteres

用于指定需要排除的组件。

useDefaultFilters

是一个bool类型,用于指定是否需要使用Spring的默认扫描规则。规则包括被@Component、@Repository、@Service、@Controller或者已经声明过@Component自定义注解标记的注解。

nameGenerator

自定义Bean的名称的Generator。

scopeResolver

自定义作用域的Generator。

scopedProxy

用于支持作用域Bean的属性,决定了是否需要创建代理对象。

resourcePattern

字符串类型,用于指定要扫描的资源模式的正则表达式。

lazyInit

bool类型,是否懒加载。

表 @ComponentScan 的属性

图 @ComponentScan注解的结构图

2.1 @Filter

@Filter注解是@ComponentScan内部定义的注解。用来定义过滤类型。其属性type 是FilterType 类型的枚举。

annotation

默认值。指定注解,用于过滤被特定注解标注的类。

assignable

指定类型,用于过滤特定类型的类。

aspectj

Aspect语法指定。

regex

正则表达式指定,用于过滤满足表达式的类名。

custom

自定义规则及过滤逻辑,通过实现ApplicationContextAware接口并覆盖getbeanDefinitionNames方法来指定自己的过滤规则。

表 FilterType的枚举值

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyComponent {
}@Configuration
@ComponentScan(lazyInit = true,basePackages = "scan.beans", includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {MyComponent.class})})
public class ScanConfig {
}@MyComponent
public class UserService {public UserService() {System.out.println("UserService实例化");}public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(ScanConfig.class);UserService userService = context.getBean(UserService.class);System.out.println(userService);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/454941.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网站项目】037物流管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

windows安装Visual Studio Code,配置C/C++运行环境(亲测可行)

一.下载 Visual Studio Code https://code.visualstudio.com/ 二.安装 选择想要安装的位置: 后面的点击下一步即可。 三.下载编译器MinGW vscode只是写代码的工具&#xff0c;使用编译器才能编译写的C/C程序&#xff0c;将它转为可执行文件。 MinGW下载链接&#xff1a;…

构造回文数组

目录 原题描述&#xff1a; 题目描述 时间&#xff1a;1s 空间&#xff1a;256M 题目描述&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 样例1输入&#xff1a; 样例1输出&#xff1a; 样例2输入&#xff1a; 样例2输出&#xff1a; 约定&#xff1a; 作…

【INTEL(ALTERA)】为什么在编译 HDMI 英特尔® FPGA IP设计示例 VHDL 变体时看到错误 (13879)?

说明 由于英特尔 Quartus Prime Pro Edition 软件版本 23.2 存在一个问题&#xff0c;您在编译 HDMI 英特尔 FPGA IP设计示例的 VHDL 变体时可能会看到以下错误&#xff1a; 错误 &#xff08;13879&#xff09;&#xff1a; VHDL 绑定指示 hdmi_rx_ram_1port_intel_mce_2010…

微信小程序的图片色彩分析,窃取网络图片的主色调

1、安装 Mini App Color Thief 包 包括下载包&#xff0c;简单使用都有&#xff0c;之前写了&#xff0c;这里就不写了 网址&#xff1a;微信小程序的图片色彩分析&#xff0c;窃取主色调&#xff0c;调色板-CSDN博客 2、 问题和解决方案 问题&#xff1a;由于我们的窃取图片的…

亚信安慧AntDB推动技术创新与满足用户需求

随着互联网技术的迅猛发展&#xff0c;大数据时代的到来&#xff0c;数据库的需求不断增长。在这样的背景下&#xff0c;国产分布式数据库正逐渐崭露头角&#xff0c;AntDB作为其中的重要代表&#xff0c;也积极参与到了这场竞争中。作为国内的技术创新者&#xff0c;AntDB不仅…

函数对象(仿函数)的相关基本概念及用法

函数对象&#xff08;仿函数&#xff09; 基本概念 重载函数调用操作符的类&#xff0c;其对象称为函数对象 函数对象使用重载的&#xff08;&#xff09;时&#xff0c;行为类似函数调用&#xff0c;因此也被称为仿函数 本质 函数对象&#xff08;仿函数&#xff09;是一…

设计模式1-访问者模式

访问者模式是一种行为设计模式&#xff0c;它允许你定义在对象结构中的元素上进行操作的新操作&#xff0c;而无需修改这些元素的类。这种模式的主要思想是将算法与元素的结构分离开&#xff0c;使得可以在不修改元素结构的情况下定义新的操作。 所谓算法与元素结构分离&#x…

LabVIEW多功能接口卡驱动

LabVIEW多功能接口卡驱动 随着自动化测试系统的复杂性增加&#xff0c;对数据采集与处理的需求不断提高。研究基于LabVIEW开发平台&#xff0c;实现对一种通用多功能接口卡的驱动&#xff0c;以支持多通道数据采集及处理功能&#xff0c;展现LabVIEW在自动化和测量领域的强大能…

网络设备-H3C设备SNMP配置及监控

目录 1. 全局模式 2. 配置SNMP V2 3. 配置SNMP V3 4. 配置SNMP Trap 5. 保存配置 6. 查看配置结果 7. H3C设备监控 1. 全局模式 SNMP 的配置工作在网络设备的全局配置模式下完成&#xff0c;在进行SNMP 配置前&#xff0c;请先进入全局配置模式。 en ##进入特权模…

玩家笔记:幻兽帕鲁搭建服务器开服教程

玩转幻兽帕鲁服务器&#xff0c;阿里云推出新手0基础一键部署幻兽帕鲁服务器教程&#xff0c;傻瓜式一键部署&#xff0c;3分钟即可成功创建一台Palworld专属服务器&#xff0c;成本仅需26元&#xff0c;阿里云服务器网aliyunfuwuqi.com分享2024年新版基于阿里云搭建幻兽帕鲁服…

C++之程序内存分配方式

程序内存布局 现在的应用程序都运行在一个虚拟内存空间里&#xff0c;以32位系统为例&#xff0c;其寻址空间为 4G&#xff0c;大部分的操作系统都将4G内存空间的一部分挪给内核调用&#xff0c;应用程序无法直接 访问这一段内存&#xff0c;这一部分内核地址成为内核态空间&am…