当前位置: 首页 > news >正文

Sprint framework Day07:注解结合 xml 配置

前言

Spring注解结合XML配置是指在Spring应用中,使用注解和XML配置的方式来进行Bean的定义、依赖注入和其他配置。这种方式可以充分利用Spring框架的注解和XML配置两种不同的配置方式的特点。

在Spring框架中,我们可以使用注解来定义Bean,如@Component、@Service、@Repository等注解,也可以使用XML配置文件来定义Bean,例如<bean>标签。通常情况下,我们可以使用其中一种方式来定义Bean,但在某些复杂的场景下,我们需要同时使用这两种方式来定义Bean。具体来说:

使用注解来定义Bean,这样可以减少XML配置文件中的内容,使代码更加简洁,易于阅读和维护。例如:

@Component("userService")
public class UserServiceImpl implements UserService {// ...
}


使用XML配置来定义Bean,这样可以提供更多的灵活性,使得对Bean的配置更加详细和准确。例如:

<bean id="userService" class="com.example.UserServiceImpl"><!-- 注入依赖 --><property name="userDao" ref="userDao"/>
</bean>


使用注解和XML配置结合的方式来定义Bean,可以根据具体要求灵活地选择采用XML配置或注解来定义Bean。例如:

<context:component-scan base-package="com.example"/><bean id="userDao" class="com.example.UserDaoImpl"/><bean id="userService" class="com.example.UserServiceImpl"><!-- 注入依赖,在XML配置中引用注解定义的Bean --><property name="userDao" ref="userDao"/>
</bean>


在这种方式下,我们可以使用注解来扫描指定包下的所有组件,使用XML配置来定义和配置Bean,实现依赖注入、AOP等功能。

综上所述,Spring注解结合XML配置是指通过同时使用注解和XML配置的方式,以适应不同的需求和场景,提供更加灵活和精细的配置。

一、开始学习注解

1、本次我们要学习的有四个注解 @Component @Repository @Service @Controller,那么他们分别是什么意思呢?

在Spring框架中,@Component@Repository@Service@Controller是用于标记类的注解,用于定义Bean的角色和作用。

  1. @Component:它是一个通用的注解,用于表示一个普通的组件类,可用于任意层次。当我们使用@Component将一个类标记为组件时,Spring容器会自动扫描并创建这个类的实例作为Bean。
  2. @Repository:它用于标记数据访问层(DAO)的组件类。主要用于对数据库的操作,包括数据的增删改查等。通过@Repository注解,Spring会将这个类识别为持久化层的Bean,常与@Autowired配合使用,进行依赖注入。
  3. @Service:它用于标记服务层(Service)的组件类。主要负责业务逻辑的处理,比如事务管理、数据校验、调用DAO层等。通过@Service注解,Spring会将这个类识别为服务层的Bean,常与@Autowired配合使用,进行依赖注入。
  4. @Controller:它用于标记控制器层(Controller)的组件类。主要用于接收用户请求,处理请求参数,调用Service层处理业务逻辑,并返回相应的视图或数据。通过@Controller注解,Spring会将这个类识别为控制器层的Bean,常与@RequestMapping等注解一起使用。

以上四个注解都是用于标记组件类,并将其注册为Spring容器中的Bean。它们的作用是告诉Spring容器哪些类需要被实例化为Bean,并提供相应的功能,如依赖注入、AOP切面等。

使用这些注解可以使代码更加清晰和模块化,也有利于后续的扩展和维护。同时,结合不同的注解,我们可以将一个大型应用程序分成不同层次的组件,使开发更加高效和可管理。

了解完这四个注解后,我们就来完成一个案例,通过案例去更直观的了解它们吧。

2、新建项目,结果如下

3、导入 spring 依赖 
 <!-- spring 的核心依赖 --><dependencies><!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.23</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.4.5</version></dependency></dependencies>
 4、在 dao 包下新建一个 UserDao 接口,在 impl 包下新建 UserDaoImpl 实现类

userDao 接口

public interface UserDao {void save();}

UserDaoImpl 实现类

@Component("userDao")
@Slf4j
public class UserDaoImpl implements UserDao {@Overridepublic void save() {log.info("insert into user_info...... ");}
}

  @Component:用于标识当前类为一个 Bena ,这样就会被 spring 容器扫描到,可以通过 value 来指定, Bean 的 id,如果不指定 value,默认的 id 就是当前类名并,将首字母改为小写(例如:userDaoImpl)

 5、在 service 包下新建一个 UserService 接口,在 impl 包下新建一个 UserServiceImpl 实现类

UserService 接口

public interface UserService {void add();}

UserServiceImpl 实现类


@Component("userService")
public class UserServiceImpl implements UserService {private UserDao userDao;/*** 通过构造方法注入 dao** @param userDao** @Autowired注解进行注入*/@Autowiredpublic UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void add() {userDao.save();}
}
 6、在 controller 包下,新建 UserController 类

@Component("userController")
public class UserController {private UserService userService;/*** 通过构造方法注入** @param userService*/@Autowiredpublic UserController(UserService userService) {this.userService = userService;}public void add() {userService.add();}}
7、 在 resources 下新建一个 spring 的 xml 文件 application.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
"><bean id="userDao" class="edu.nf.ch07.dao.impl.UserDaoImpl"/><bean id="userService" class="edu.nf.ch07.service.impl.UserServiceImpl"><constructor-arg name="userDao" ref="userDao"/></bean><bean id="userController" class="edu.nf.ch07.controller.UserController"><constructor-arg name="userService" ref="userService"/></bean>
</beans>

这个案例是通过使用 @Component 注解去装配一个 bean。

8、测试
public class Main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");UserController bean = context.getBean(UserController.class);bean.add();}}

测试结果

9、分析

在实现类和 UserControlelr 类都是用了 @Component 注解去装配一个 bean ,而且还是带参数的,那么这个参数有什么用呢?看下图:

使用Spring框架进行依赖注入的配置文件,它采用了XML格式来描述组件及其之间的依赖关系。

在这个配置文件中,定义了三个Bean:

  1. userDao:它的类为edu.nf.ch07.dao.impl.UserDaoImpl。这个Bean用于访问数据库,并提供了数据访问操作。

  2. userService:它的类为edu.nf.ch07.service.impl.UserServiceImpl。这个Bean用于封装一些具体的业务逻辑操作,并调用userDao进行数据访问。

  3. userController:它的类为edu.nf.ch07.controller.UserController。这个Bean用于接收用户请求,通过调用userService处理业务逻辑,最终返回相应的视图或数据。

  4. 在XML配置文件中,name用于指定要注入的属性或构造函数参数的名称。它通常和valueref等属性一起使用,在显式配置Bean时指定相应的属性或构造函数参数。name属性的取值为一个字符串,表示目标属性或构造函数参数的名称。

  5. 在XML配置文件中,ref用于指定依赖注入的目标Bean。它的取值为一个Bean的ID。在给某个属性或构造函数参数注入值时,通过ref指定目标Bean的ID,Spring容器会自动解析这个依赖关系,并将相应的Bean实例注入到目标位置。

在这些Bean之间,存在一定的依赖关系。userDaouserService依赖,因此在userService的构造函数中使用constructor-arg标签注入userDao。同样,userServiceuserController依赖,因此在userController的构造函数中使用constructor-arg标签注入userService

这种基于XML的配置方式被称为“显式配置”,它会告诉Spring容器哪些Bean需要被实例化,并建立它们之间的依赖关系。通过使用这种方式,我们可以将组件之间的关系直观地描述出来,同时可以灵活地进行配置和修改。

 二、使用特定注解定义各个类

1、 Dao 层 @Repository
@Repository("userDao")
public class UserDaoImpl implements UserDao {@Overridepublic void save() {log.info("insert into user_info...... ");}
}
2、service 层 @Service

@Service("userService")
public class UserServiceImpl implements UserService {private UserDao userDao;/*** 通过构造方法注入 dao** @param userDao** @Autowired注解进行注入*/public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void add() {userDao.save();}
}
3、controller 层 @Controller

@Controller("userController")
public class UserController {private UserService userService;/*** 通过构造方法注入** @param userService*/public UserController(UserService userService) {this.userService = userService;}public void add() {userService.add();}}
4、改配置文件
<?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.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.2.xsd
"><!-- 启用注解扫描 , 指定扫描的包 --><context:component-scan base-package="edu.nf.ch07"/></beans>

在Spring配置文件中,<context:component-scan>用于启用注解扫描,并指定要扫描的包路径。通过这个配置,Spring容器会自动扫描指定包及其子包下的类,并将它们注册为Bean。上述示例中,使用<context:component-scan>配置启用了注解扫描功能,并通过base-package属性指定了要扫描的包路径为edu.nf.ch07。这意味着Spring容器将会扫描该包及其子包下的类,查找带有特定注解(如@Component@Service@Repository等)的类,并将其注册为Bean。

5、测试
public class Main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");UserController bean = context.getBean(UserController.class);bean.add();}}

测试结果

 6、使用@Component 和使用 @Controller @Repository @Service 的区别

@Component@Controller@Repository@Service都是Spring中的注解,它们都是@Component注解的扩展。使用它们可以标记一个类作为组件,并将其注册到Spring容器中。它们之间的区别如下:

  1. @Component:通用注解,可用于任何类。
  2. @Controller:用于标记控制器层的组件,常用于SpringMVC应用程序。
  3. @Repository:用于标记数据访问层的组件,表示该组件负责数据访问,常用于与数据库交互的场景。
  4. @Service:用于标记业务逻辑层的组件,表示该组件负责业务处理,常用于编写业务逻辑。

使用<context:component-scan>配置时,它会扫描指定包及其子包下的标记了@Component@Controller@Repository@Service注解的类,并将其注册为Bean。因此,在使用<context:component-scan>时,使用哪种注解来标记类并没有影响。

但是,建议在不同层次的组件上使用相应的注解,以便更好地组织代码,并使代码更易于理解和维护。这也是所谓的“约定优于配置”原则的一种体现,即通过预定义的注解来简化配置,提高代码清晰度和可读性。

三、使用注解结合 xml 开发有什么好处?


注解和XML配置结合的方式可以提供更灵活和可扩展的依赖注入配置方案。下面是使用注解和XML配置结合的几个好处:
增加可读性和易维护性:通过使用注解,可以将依赖注入相关的配置信息直接写在类的代码中,使得代码更加直观和可读。同时,将一些通用的配置信息(比如数据库连接等)放在XML配置文件中,可以提高配置信息的可维护性和重用性。
灵活性和扩展性:注解可以灵活地应用于各种情况,例如使用 @Autowired 注解进行自动注入、使用 @Qualifier 注解指定具体的Bean、使用 @Primary 注解指定默认的Bean等。这些注解可以与XML配置文件结合使用,提供更细粒度的依赖注入控制和配置灵活性。
降低耦合性:通过使用注解和XML配置结合的方式,可以将实现类与接口之间解耦。使用 @Qualifier 注解可以根据需要选择具体的实现类,在不改变代码的情况下更换依赖的实现类。同时,@Primary 注解可以指定默认的实现类,减少了代码中对具体实现类的直接引用,进一步降低了耦合性。
总的来说,注解和XML配置结合的方式可以提供更灵活、可读性更好、可维护性更高、扩展性更强、耦合性更低的依赖注入配置方案。通过合理选择和使用注解和XML配置,可以更好地管理和控制对象之间的依赖关系。
 

四、gitee 案例

案例完整地址:https://gitee.com/qiu-feng1/spring-framework.git

相关文章:

Sprint framework Day07:注解结合 xml 配置

前言 Spring注解结合XML配置是指在Spring应用中&#xff0c;使用注解和XML配置的方式来进行Bean的定义、依赖注入和其他配置。这种方式可以充分利用Spring框架的注解和XML配置两种不同的配置方式的特点。 在Spring框架中&#xff0c;我们可以使用注解来定义Bean&#xff0c;如…...

LiveGBS流媒体平台GB/T28181功能-国标流媒体服务同时兼容内网收流外网收流多网段设备收流

LiveGBS流媒体平台GB/T28181功能-国标流媒体服务同时兼容内网收流外网收流多网段设备收流 1、背景2、设备接入播放2.1、查看通道2.2、直播播放 3、默认收流地址配置4、其它网络设备收流配置5、搭建GB28181视频直播平台 1、背景 服务器部署的时候&#xff0c;可能有多个网卡多个…...

js题解(四)

文章目录 批量改变对象的属性判断是否包含数字判断是否符合指定格式 批量改变对象的属性 给定一个构造函数 constructor&#xff0c;请完成 alterObjects 方法&#xff0c;将 constructor 的所有实例的 greeting 属性指向给定的 greeting 变量。 function alterObjects(const…...

如何进行大数运算和高精度计算?

大数运算和高精度计算是在计算机编程中常见的需求&#xff0c;尤其是当处理大整数、分数、复数、浮点数等需要更多位数的数据时。在C语言中&#xff0c;由于原生的数据类型有限&#xff0c;您需要使用自定义的数据结构和算法来执行大数运算和高精度计算。在本文中&#xff0c;我…...

身份证读卡器跟OCR有何区别?哪个好?

二代身份证读卡器&#xff08;以下简称读卡器&#xff09;和OCR&#xff08;光学字符识别&#xff09;是两种常见的身份证信息获取技术&#xff0c;它们在原理、功能和应用方面存在一些区别。下面将详细介绍二者的区别并探讨哪个更好。 1. 原理&#xff1a; - 读卡器&#xff…...

华为云云耀云服务器L实例评测 | 实例评测使用之硬件参数评测:华为云云耀云服务器下的 Linux 网络监控神器 bmon

华为云云耀云服务器L实例评测 &#xff5c; 实例评测使用之硬件参数评测&#xff1a;华为云云耀云服务器下的 Linux 网络监控神器 bmon 介绍华为云云耀云服务器 华为云云耀云服务器 &#xff08;目前已经全新升级为 华为云云耀云服务器L实例&#xff09; 华为云云耀云服务器是什…...

C++ 设计模式 —— 组合模式

C 设计模式 —— 组合模式 0. 引用连接 本文主要的思路和代码&#xff0c;来自于对以下连接的学习和实现&#xff1a; 组合模式 1. 引言 1.1 什么是组合模式&#xff1f; 组合模式的定义组合模式的作用 组合模式是一种行为型设计模式&#xff0c;它将对象组合成树形结构以…...

华为云Stack的学习(九)

十、华为云Stack灾备服务介绍 1.云硬盘备份VBS 云硬盘备份服务&#xff08;VBS&#xff0c;Volume Backup Service&#xff09;可为云硬盘&#xff08;EVS&#xff0c;Elastic Volume Service&#xff09;创建备份&#xff0c;利用备份数据恢复云硬盘&#xff0c;最大限度保障…...

Flink中jobmanager、taskmanager、slot、task、subtask、Parallelism的概念

场景 一个工厂有三个车间每个车间两条生产线 生产流程如下 原料->加工->过滤->分类->美化->包装->下线 JobManager&#xff1a;工厂 在上述场景中&#xff0c;工厂就是jobManager&#xff0c;负责协调、调度和监控整个生产过程 TaskManager&#xff1a;车间…...

OpenHarmony docker环境搭建

OpenHarmony docker环境搭建 要求一台安装ubuntu的虚拟机,vscode软件 安装docker 在 Ubuntu 上安装 Docker 非常直接。我们将会启用 Docker 软件源&#xff0c;导入 GPG key&#xff0c;并且安装软件包。 首先&#xff0c;更新软件包索引&#xff0c;并且安装必要的依赖软件…...

【计算机网络】网络编程接口 Socket API 解读(11)

Socket 是网络协议栈暴露给编程人员的 API&#xff0c;相比复杂的计算机网络协议&#xff0c;API 对关键操作和配置数据进行了抽象&#xff0c;简化了程序编程。 本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍&#xff0c;从而更好的理解 socket 编程。…...

Qt工具开发,该不该跳槽?

Qt工具开发&#xff0c;该不该跳槽? 就这样吧&#xff0c;我怕你跳不动。 嵌入式UI&#xff0c;目前趋势是向着LVGL发展。QT已经在淘汰期了。很多项目还在用&#xff0c;但技术上已经落后。QT短期内不会全面淘汰&#xff0c;但退位让贤的大趋势已经很清楚了。 最近很多小伙伴…...

【深度学习】DDPM,Diffusion,概率扩散去噪生成模型,原理解读

看过来看过去&#xff0c;唯有此up主&#xff0c;非常牛&#xff1a; Video Explaination(Chinese) 1. DDPM Introduction q q q - 一个固定&#xff08;或预定义&#xff09;的正向扩散过程&#xff0c;逐渐向图像添加高斯噪声&#xff0c;直到最终得到纯噪声。 p θ p_θ p…...

HT8699:内置 BOOST 升Y双声道音频功率放大器

HT8699是一款内置BOOST升Y模块的立体声音频功率放大器。HT8699具有AB类和D类切换功能&#xff0c;在受到D类功放EMI干扰困扰时&#xff0c;可切换至AB类音频功放模式。 在D类模式下&#xff0c;内置的BOOST升Y模块可通过外置电阻调节升Y值&#xff0c;即使是锂电池供电&#xf…...

利达卓越:关注环保事业,持续赋能科技

随着全球环境问题的日益突出,绿色金融作为一种新兴的金融模式逐渐受到各国的重视。绿色金融是指在金融活动中,通过资金、信贷和风险管理等手段,支持环境友好和可持续发展的项目和产业。绿色金融的出现是为了应对气候变化、资源短缺、污染问题等现实挑战,促进经济的绿色转型和可…...

Spring MVC中通过配置文件配置定时任务

Spring MVC中配置定时任务&#xff08;配置文件方式&#xff09; 1.步骤 1.步骤 1-1 在springmvc.xml&#xff08;配置文件&#xff09;的beans中添加 xmlns:task"http://www.springframework.org/schema/task" http://www.springframework.org/schema/task http…...

AI项目十六:YOLOP 训练+测试+模型评估

若该文为原创文章&#xff0c;转载请注明原文出处。 通过正点原子的ATK-3568了解到了YOLOP&#xff0c;这里记录下训练及测试及在onnxruntime部署的过程。 步骤&#xff1a;训练->测试->转成onnx->onnxruntime部署测试 一、前言 YOLOP是华中科技大学研究团队在2021年…...

Flink报错could not be loaded due to a linkage failure

文章目录 1、报错2、原因3、解决 1、报错 在Flink上提交作业&#xff0c;点Submit没反应&#xff0c;F12看到接口报错信息为&#xff1a; 大概意思是&#xff0c;由于链接失败&#xff0c;无法加载程序的入口点类xx。没啥鸟用的信息&#xff0c;去日志目录继续分析&#xff1a…...

网络工程师--网络安全与应用案例分析

前言 需要网络安全学习资料的点击链接&#xff1a;【282G】网络安全&黑客技术零基础到进阶全套学习大礼包&#xff0c;免费分享&#xff01; 案例一&#xff1a; 某单位现有网络拓扑结构如下图所示&#xff0c;实现用户上网功能&#xff0c;该网络使用的网络交换机均为三…...

了解油封对汽车安全的影响?

油封也称为轴封或径向轴封&#xff0c;是车辆发动机、变速箱和其他各种机械系统中的重要部件。它们的主要功能是阻止重要发动机部件的液体(例如油或冷却剂)泄漏&#xff0c;同时防止污染物进入。这些看似简单的任务&#xff0c;但对汽车的安全性和可靠性有着深远的影响。 油封…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...