分层解耦-04.IOCDI-IOC详解

news2024/11/25 16:36:22

一.Bean的声明 

springboot为了更好地标识web应用开发中bean对象到底归属于哪一层,在@Component注解的基础上又衍生出了三个注解@Controller、@Service和@Repository。分别应用于Controller层,Service层和Dao层。推荐使用衍生注解,当无法判断该bean对象到底是属于哪一层时,使用@Component注解。

package com.gjw.dao.impl;

import com.gjw.dao.EmpDao;
import com.gjw.pojo.Emp;
import com.gjw.utils.XmlParserUtils;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

import java.util.List;

//@Component  // IOC:控制反转,将实现类对象交给容器。将当前类交给IOC容器管理,成为IOC容器中的bean
@Repository     // Dao层
public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}
package com.gjw.service.impl;

import com.gjw.dao.EmpDao;
import com.gjw.pojo.Emp;
import com.gjw.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.List;

//@Component  // IOC:控制反转,将实现类对象交给容器。将当前类交给IOC容器管理,成为IOC容器中的bean
@Service
public class EmpServiceA implements EmpService {
    @Autowired  // DI:依赖注入,service依赖于dao,运行时IOC容器会提供该类型的bean对象,并赋值给该变量
    private EmpDao empDao;
    @Override
    public List<Emp> listEmp() {
        List<Emp> empList = empDao.listEmp();
        empList.stream().forEach(emp ->
        {
            if ("1".equals(emp.getGender())) {
                emp.setGender("男");
            } else if ("2".equals(emp.getGender())) {
                emp.setGender("女");
            }
            if ("1".equals(emp.getJob())) {
                emp.setJob("讲师");
            } else if ("2".equals(emp.getJob())) {
                emp.setJob("班主任");
            } else if ("3".equals(emp.getJob())) {
                emp.setJob("就业指导");
            }
        });
        return empList;
    }
}

在controller代码中就不用加@Controller注解了,因为@RestController注解中已经有了@Controller注解 

@RestController注解源码:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Controller;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}

@RestController = @Controller + @ResponseBody

将原来的@Component注解替换为对应层的注解,刷新后依然可以看到数据,证明成功

二.Bean的名字

在我们声明一个bean时,每一个bean都有一个名字。在声明一个bean时,我们可以通过注解当中的value属性来指定一个bean的名字,如果不指定,默认就是类名的首字母小写。

 将程序运行起来之后,在控制台中进入Actuator,点击右边按键。其中非黄色部分就是自己定义的bean对象的类,而点击三角显示出来的就是其bean的名字。

@Service和@Repository源码

// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)

package org.springframework.stereotype;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.stereotype;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

我们可以通过使用注解中的value方法来为bean对象重新起一个名字。

@Service(value = "serviceA")

通过value指定的bean对象的名字,可以将value省略。

@Service("serviceA")

 已修改。一般不会修改名字。

三.Bean组件扫描

我们将dao移出来,放在java包下,与com.gjw平级。 再次启动程序。

程序报错,报错原因是EmpServiceA这个类中要找的EmpDao这个接口的实现类发现找不到了。

为什么会找不到呢?原因一定在将dao包移动到和com.gjw包平级的位置有关。这就涉及到bean的组件扫描问题。

 也就是说,bean组件扫描只会扫描com.gjw包下的所有包及其子包。而dao包与其平级,自然不会被扫描到。因此也就找不到。

四.解决办法

方法一:手动设置包扫描@ComponentScan(指定扫描包)(不推荐)

通过value属性和basePackages属性都可以来指定要扫描哪个包。返回类型为字符串数组。

@ComponentScan({"dao","com.gjw"})
@SpringBootApplication  // 默认扫描当前包及其子包
public class SpringbootWebReqRespApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebReqRespApplication.class, args);
    }

}
    

手动指定,一旦手动指定,那么默认的com.gjw包就会没有,需要手动添加上去。

成功

方法二:将所写代码全部放在启动类所在包及其子包下,按照规范来(推荐)

五.总结

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java-数据结构-反射、枚举 |ू・ω・` )

目录 ❄️一、反射&#xff1a; 1、定义&#xff1a; 2、用途&#xff1a; 3、反射相关的类&#xff1a; 4、Class类&#xff1a; 1、Class类中相关的方法&#xff1a; 5、Class反射实例&#xff1a; 1、获得Class对象的三种方式&#xff1a; 2、反射的使用&#xff1a; 6、反…

网络基础擅长组建乐队

让我们荡起双桨 来说说网络吧 现有计算机要进行协作&#xff0c;网络的产生是必然的 局域网&#xff1a;计算机数量更多了, 通过交换机和路由器连接在一起 广域网&#xff1a;将远隔千里的计算机都连在一起 交换机路由器等设备就应运而生 计算机是人的工具&#xff0c;人要协…

layernorm笔记

文章目录 layer norm的解释二维三维 batchnorm和layernorm主要的区别为什么要在序列转录模型中使用layer norm&#xff1f; layer norm的解释 二维 红色为batchnorm&#xff0c;蓝色为layer norm batchnorm对每一个特征算均值和方差 layer norm对每一个批次算均值和方差 三…

窗口系统与图形绘制接口

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 当我们想要进行底层图形应用(GUI)开发时,往往需要用到窗口系统和图形库,这里简单介绍一下 视窗系统(window system)与通信协议 下面内容主要针对Unix-like操作系统 视窗系统是以使用视窗作为主要特征之一的图形用…

【含开题报告+文档+PPT+源码】基于SSM + Vue的养老院管理系统【包运行成功】

开题报告 随着社会的发展和经济的进步&#xff0c;人口老龄化问题逐渐凸显。统计数据显示&#xff0c;全球范围内的老龄人口比例正在逐年上升&#xff0c;养老需求也随之增长。养老院作为提供专业养老服务的机构&#xff0c;承担着照料老人、提供医疗保健和社交活动等责任。传…

DVWA Brute Force篇暴力破解 Low/Medium/Hight

这里就不再赘述环境搭建&#xff0c;就默认你已经做好环境搭建的准备了.接下来就步入正题(我的bp是汉化) 任务一&#xff0c;设置级别为low级别&#xff0c;创建好我们的字典文件 任务二 开启抓包&#xff0c;并且我们输入错误的账户密码 &#xff08;当我知道账户名称为admin时…

Nginx06-静态资源部署

零、文章目录 Nginx06-静态资源部署 1、静态资源概述 静态资源&#xff1a;是在Web开发中不经常改变的文件&#xff0c;比如图片、CSS样式表、JavaScript脚本文件等。这些资源通常是预先编译好的&#xff0c;不需要服务器端的动态处理。动态资源&#xff1a;是在Web开发中需…

fiddler抓包19_模拟IP地址(如异地IP)

课程大纲 使用场景举例&#xff1a;北京模拟海南IP地址“182.118.99.12”发送请求。 ① 打开CustomRules.js文件&#xff1a;Fiddler快捷键“CtrlR”(或鼠标点击&#xff0c;菜单栏 - Rules“规则” - Customize Rules“自定义规则”)。 ② 添加代码&#xff0c;保存&#xff1…

SpringBoot在线教育系统:架构设计与技术选型

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

计算机网络——DNS

提供域名——>ip地址的转换 分层命名 分布式解析 怎么样维护 DNS实现在边缘系统——传输层及其以上 还提供别名——>规范名字的转换——>ip 负载均衡是一种用于在多个计算资源&#xff08;如服务器、网络设备等&#xff09;之间分配工作负载的技术。其主要目的是…

最小生成树prim算法kruskal算法

最小生成树 在一个无向图中求一棵树(n-1条边&#xff0c;无环&#xff0c;连通所有点)而且这棵树的边的权和最小 prim(普利姆)算法 prim算法有叫加点法&#xff0c;我们先标定一个点&#xff0c;然后寻找与这个点相连的边的权值最小的点&#xff0c;不断重复此操作&#xff…

【鸿蒙学习】深入解析鸿蒙应用与元服务:含义、区别、应用场景及创建方法

文章目录 鸿蒙应用&#xff08;HarmonyOS App&#xff09;含义用于干什么优缺点 元服务&#xff08;Atomic Service&#xff09;含义用于干什么优缺点 鸿蒙应用与元服务的区别创建方法鸿蒙应用的创建元服务的创建 总结 随着科技的不断进步&#xff0c;操作系统也在不断迭代更新…

医院管理自动化:Spring Boot技术实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…

上传文件失败,请检查阿里云配置信息:[The specified bucket is not valid.

-- 十一假期结束 -- 去年今日此门中&#xff0c;人面挑花相应红。 -- 人面不知何处去&#xff0c;桃花依旧笑春风。

UART驱动学习三(TTY驱动部分源码解析)

目录 全局框架图一、tty_io.c 分析1. 关键数据结构和定义2. 文件操作结构体3. 初始化和注册4. 读写操作5. 挂起和恢复6. 信号处理7. 设备类8. 控制台通知9. 辅助函数10. 代码功能11. 带有注释的部分tty_io.c源码 二、tty_ldisc.c 分析1. 关键数据结构和定义2. 行规程操作函数3.…

从零开始打造华丽的国庆生活记录本地HTML网站

目录 目录 前言 准备工作 所需工具 文件夹结构 基础知识入门 HTML基础 CSS基础 JavaScript基础 步骤详解 1. 创建项目文件夹 2. 编写HTML文件 3. 添加CSS样式 4. 增加交互功能 5. 添加图片和视频 6. 美化网站 7. 实现响应式设计 8. 测试与优化 附加功能 创建…

Windows 搭建 Gitea

一、准备工作 1. 安装 Git&#xff1a;Gitea 依赖 Git 进行代码管理&#xff0c;所以首先需要确保系统中安装了 Git。 下载地址&#xff1a;https://git-scm.com/downloads/win 2. 安装数据库&#xff08;可选&#xff09; 默认情况下&#xff0c;Gitea 使用 SQLite 作为内…

【springboot】使用代码生成器快速开发

接上一项目&#xff0c;使用mybatis-plus-generator实现简易代码文件生成 在fast-demo-web模块中的pom.xml中添加mybatis-plus-generator、freemarker和Lombok依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator&…

Windows 11:如何轻松安装或卸载 Copilot 应用(多种方法)

起初&#xff0c;Copilot 是一个与 Windows 11 和 Windows 10 系统紧密结合的内置 AI 助手&#xff0c;能够通过回答问题、调整系统设置等功能来提高你的工作效率。 但从 Windows 11 24H2 开始&#xff0c;Copilot 功能已经从系统中剥离出来&#xff0c;成了一个基于 Microsoft…

【kubernetes】环境准备及K8S二进制安装【最新最全】

一,规划 1,架构 主节点(3台 master)+ 工作节点 (1台 node1) Pod网段: 10.0.0.0/16 Service网段: 10.255.0.0/16 实验环境规划: 操作系统:centos7.6 配置: 4Gib内存/6vCPU/100G硬盘 注意:也可以用4vCPU 网络:NAT 开启虚拟机的虚拟化: 2,K8S集群角色 Ip 主机名…