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

Spring学习笔记9 SpringIOC注解式开发

Spring学习笔记8 Bean的循环依赖问题_biubiubiu0706的博客-CSDN博客

注解的存在主要是为了简化XML的配置.Spring6倡导全注解式开发

回顾下

注解怎么定义,注解中的属性怎么定义

注解怎么使用

通过反射机制怎么读取注解

注解的自定义

注解的使用

通过反射机制怎么读取注解

IOC之包扫描原理

需求:给定一个包名,扫描所有类,只要有@Component注解,就创建该类对象,然后放到Map集合中

Key为注解的value,Value为对象

bean包下新建

package com.example.client;import com.example.annotation.Component;import java.io.File;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;/*** 手写组件扫描* @author hrui* @date 2023/9/24 18:20*/
public class ComponentScan {public static void main(String[] args) throws Exception{//创建存放注解值的key和对象的容器Map<String,Object> beanMap=new HashMap<>();//目前只知道包名,扫描包下所有类,当类上有@Component注解时候,实例化该对象,放到MapString packageName="com.example.bean";//开始扫描//.这个正则表达式代表任意字符,这里的"."必须是一个普通的"."字符,不能是正则表达式中的"."String packagePath = packageName.replaceAll("\\.", "/");System.out.println(packagePath);URL url = ClassLoader.getSystemClassLoader().getResource(packagePath);String path = url.getPath();System.out.println(path);//获取绝对路径下所有文件File files=new File(path);File[] listFile = files.listFiles();Arrays.stream(listFile).forEach(f->{try {System.out.println(f.getName());System.out.println(f.getName().split("\\.")[0]);//拼接包名 获得类名String className=packageName+"."+f.getName().split("\\.")[0];System.out.println(className);//通过反射机制解析注解Class<?> clazz = Class.forName(className);//判断类上有没有@Component注解if(clazz.isAnnotationPresent(Component.class)){//获取注解Component annotation = clazz.getAnnotation(Component.class);String key=annotation.value();//有该注解就创建对象Object o = clazz.newInstance();beanMap.put(key, o);}} catch (Exception e) {e.printStackTrace();}});System.out.println(beanMap);}
}

上面就是包扫描的原理

声明Bean的注解,常见的包括4个

@Compoent   组件

@Controller   控制器

@Service   业务

@Repository   DAO

新建模块spring-010

pom.xml

<dependencies><!--Spring依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.10</version></dependency><!--junit单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--Log4j2依赖--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.19.0</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.19.0</version></dependency>
</dependencies>

引入日志文件,Spring默认用的log4j2   在resources目录下固定名称log4j2.xml日志文件即可

<?xml version="1.0" encoding="UTF-8"?>
<configuration><loggers><!--level指定⽇志级别,从低到⾼的优先级:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF--><root level="INFO"><appender-ref ref="spring6log"/></root></loggers><appenders><!--输出⽇志信息到控制台--><console name="spring6log" target="SYSTEM_OUT"><!--控制⽇志输出的格式--><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/></console></appenders>
</configuration>

上面4个注解的源码

@Component

看下@Controller   @Service   @Repository 

说明@Component是老大  一样的效果

其实作用是一样的,只为增加程序的可读性

@Controller表示控制层    @Service表示业务层    @Repository表示持久层

那我非不想这么写,都用@Component行不行,答案是:可以.你喜欢,你随意

@Component   @Controller  @Service @Repository  这4个常用的Spring注解如何使用

1.引入spring-context依赖--->里面的spring--aop依赖   这个已经引入

2.在Spring配置文件中引入命名空间

3.配置包扫描

4.希望将对象交由Spring管理的类上加注解

测试

实际上,即使不取名,默认也有名,类名首字母小写

将4个bean的注解里的vlaue去掉

例如

SpringIOC解决多个包扫描问题

两种解决方案:

1.在配置文件中指定多个包,用逗号隔开

2.指定多个包的共同父包

测试

指定父包

SpringIOC注解式开发之选择性实例化Bean

例如某个包下有很多Bean,分别标注了@Component  @Controller  @Service  @Repository

现在由于某种业务需要,允许@Controller注解的参与Bean管理,其他不实例化.

第一种解决方案

测试:只有A和C 创建对象了

第二种解决方案

负责注入的注解

@Component  @Controller  @Service  @Repository 这四个注解是用来声明Bean的.

声明后这些Bean交由Spring管理.

如何给Bean的属性赋值,需要以下注解

@Value 用于注入简单类型  可以用在属性上   set方法上   构造方法的形参上

@Autowired  用于注入非简单类型  用于 构造方法上   方法上  形参上  属性上  注解上

@Qualifier

@Resource

@Value注解是专门用来注入简单类型的,专门用来代替

示例

现在不需要set方法

新建个配置文件

测试

再测一个

另外 @Value还可以用在set方法上

@Value还可以用在构造方法中

再测

注意:这样不行

SpringIOC注解之@Autowired和 @Qualifier

@Autowired注解可以用来注入非简单类型

单独使用@Autowried注解.默认根据类型匹配----->byType

如果要byName@Autowired和@Qualifier需要一起使用

注意:@Autowired单独使用 都是byType

需要byName要和@Qualifier一起使用

另外建个包com.example2

持久层接口

持久层实现类

业务层接口

业务层实现类

新建配置文件用以包扫描

测试

如果我接口下有多个实现类

就报错了  原因 它找到两个

需要@Autowired和@Qualifier联合使用 

在Spring中,@Autowired 注解默认会使用"byType"方式进行自动装配,它会尝试按照被注入的类型(数据类型)去寻找匹配的依赖,然后将依赖注入到目标字段或方法参数中。如果存在多个匹配的依赖对象(同一类型的多个Bean),并且无法确定要注入哪一个时,它会引发一个异常。

如果 "byType" 自动装配失败,Spring 不会自动尝试 "byName" 自动装配。如果有多个相同类型的 Bean,但您希望显式选择其中一个进行注入,您可以使用 @Qualifier 注解与 @Autowired 结合使用,以指定要注入的 Bean 的名称

测试

下面演示@Autowired的可以自动装配的位置,@Autowired单独使用时,有两个同类型的会报错,

因此先把OrderDaoForMysql或者OrderDaoForOracle注释掉一个

下面演示@Autowired的可以自动装配的位置

@Autowired在构造方法上

测试

@Autowired在构造方法参数上

测试

有给属性赋值的构造方法,省略掉@Autowired行不行 (注意:这里要求构造方法必须只有一个,且该构造方法给属性赋值)

测试

@Autowired放在set方法上

关于@Resource注解

@Resource注解也可以完成非简单类型注入.它和@Autowired的区别是

1.@Resource是JDK扩展包中的注解,是javaEE的.更具通用性

2.@Autowired注解是Spring框架自己的

3.@Resource注解默认byName,为指定名字使用属性名为name.通过name找不到会自动启用byType装配

4.@Autowired默认byType,找不到的话不会自动用byName,需要通过@Qualifier来byName

5.@Resource注解用在属性上,set方法上

6.@Autowired注解用在属性上,set方法上,构造方法上,构造方法参数上

@Resource注解属于JDK扩展包(如果是JDK8不需要额外引入依赖,高于JDK11或低于JDK8需要额外引入依赖)

注意:Spring6开始不再支持JAVAEE,它支持JAKARTA9(需要引入依赖)

如果用的Spring6的引依赖

<dependency><groupId>jakarta.annotation</groupId><artifactId>jakarta.annotation-api</artifactId><version>2.1.1</version>
</dependency>

如果用的Spring5 

<dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version>
</dependency>

 

这用的Spring6  引入依赖

新建个包

持久层接口

持久层实现类

业务层

新建配置文件包扫描

测试

测试放在set方法上

测试

@Resource不能放在构造方法上

@Resource(name="xxxxx")如果不指定名字  单写个@Resource会将属性名作为名字,如果找不到bean,会用byType

如果

SpringIOC全注解开发  将Spring配置文件干掉

相关文章:

Spring学习笔记9 SpringIOC注解式开发

Spring学习笔记8 Bean的循环依赖问题_biubiubiu0706的博客-CSDN博客 注解的存在主要是为了简化XML的配置.Spring6倡导全注解式开发 回顾下 注解怎么定义,注解中的属性怎么定义 注解怎么使用 通过反射机制怎么读取注解 注解的自定义 注解的使用 通过反射机制怎么读取注解 I…...

【新日标习题集】第13課 までのまとめ (discarded)

2. 学校にコンピューターがごだいあります。 这个句子好像有点问题&#xff0c;辞典中没有查到有「ごだい」这个单词 学校里有5台电脑。 5. わたしは英語がよくわかります。 我很懂英语。...

Java基础常考知识点(基础、集合、异常、JVM)

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有需要我的支持&#xff0c;请私信或评论留言&#xff01; Java基础常考知识点…...

虚拟机桥接模式下没有无线网卡选项

我以为是雷电模拟器占用了网卡的缘故&#xff0c;但想起之前可能修改了无线网卡的某些内容&#xff0c;于是到网络属性里面查看。 如下所示&#xff0c;原来是之前我不小心把这个红箭头指向的项目取消勾选了。...

设计模式笔记

关于设计模式 1. 如何阅读本文 略 2. 面向对象程序设计简介 2.1 面向对象程序设计基础 面向对象程序设计 &#xff08;Object-Oriented Programming&#xff0c;缩写为 OOP&#xff09;是一种范式&#xff0c;其基本理念是将 数据块 及 与数据相关的行为 封装成为特殊的、…...

c==ubuntu+vscode debug redis7源码

新建.vscode文件夹&#xff0c;创建launch.json和tasks.json {"version": "0.2.0","configurations": [{"name": "C/C Launch","type": "cppdbg","request": "launch","prog…...

java字符串储存底层原理

字符串原理:原理1: 内存原理 (1)直接赋值给字符串,会把这个字符串放到常量池里,如果之后出现重复使用这个字符串的,就会直接从这个常量池中去引用,不会再去new一个字符串 (2)new出来的字符串不会重复使用,而是开辟一个新的空间存储原理2: 字符串中的""比较的是什么?…...

c++获取当前时间的字符串

代码 void getNowTimePrefix(std::string& prefix) {std::time_t nowTime;struct tm* p new tm;std::time(&nowTime);localtime_s(p, &nowTime);int year p->tm_year 1900;int month p->tm_mon 1;int day p->tm_mday;int hour p->tm_hour;int …...

【精品】通用Mapper 批量更新bug解决方案

问题描述 环境&#xff1a;mysql8.xmybatis3.5.13tk.mybatis4.2.3 在使用tk.mybatis做批量更新时&#xff0c;程序会报错&#xff0c;说是执行的SQL语法错误&#xff0c;经研究源代码发现tk.mybatis在实现批量更新时是通过多次执行update语句实现的。这本身就不符合MySQL批量…...

腾讯mini项目-【指标监控服务重构-会议记录】2023-07-06

7/6 会议记录 Profile4个步骤 解压kafka消息初始化性能事件&#xff0c;分析事件将数据写入kafkaRun 开始执行各stage handler 上报耗时到otel-collector。。。 // ConsumerDispatchHandler consumer // // param msg *sarama.ConsumerMessage // param consumer *databus.K…...

【React】函数式组件和类式组件的用法和逻辑

组件的使用 当应用是以多组件的方式实现&#xff0c;这个应用就是一个组件化的应用 注意&#xff1a; 组件名必须是首字母大写虚拟DOM元素只能有一个根元素虚拟DOM元素必须有结束标签 < /> 渲染类组件标签的基本流程React 内部会创建组件实例对象调用render()得到虚拟 …...

题目 1061: 二级C语言-计负均正

从键盘输入任意20个整型数&#xff0c;统计其中的负数个数并求所有正数的平均值。 保留两位小数 样例输入 1 2 3 4 5 6 7 8 9 10 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 样例输出 10 5.50 解题思路&#xff1a; 如题所示&#xff0c;输入20个正负数&#xff0c;---》求付数的个…...

数位和(C++)

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…...

[牛客复盘] 牛客周赛round13 20230924

[牛客复盘] 牛客周赛round13 20230924 总结矩阵转置置2. 思路分析3. 代码实现 小红买基金1. 题目描述2. 思路分析3. 代码实现 小红的密码修改1. 题目描述2. 思路分析3. 代码实现 小红的转账设置方式1. 题目描述2. 思路分析3. 代码实现 小红打boss1. 题目描述2. 思路分析3. 代码…...

mybatsi-MyBatis的逆向工程

mybatsi-MyBatis的逆向工程 一、前言二、创建逆向工程的步骤1.添加依赖和插件2.创建MyBatis的核心配置文件3.创建逆向工程的配置文件4.执行MBG插件的generate目标 一、前言 正向工程&#xff1a;先创建Java实体类&#xff0c;由框架负责根据实体类生成数据库表。 Hibernate是支…...

转转闲鱼交易猫链接源码 支持二维码收款

最新仿二手闲置链接源码 后台一键生成链接&#xff0c;后台管理教程&#xff1a;解压源码&#xff0c;修改数据库config/Congig 不会可以看源码里有教程 下载程序&#xff1a;https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3...

Python爬虫基础(三):使用Selenium动态加载网页

文章目录 系列文章索引一、Selenium简介1、什么是selenium&#xff1f;2、为什么使用selenium3、安装selenium&#xff08;1&#xff09;谷歌浏览器驱动下载安装&#xff08;2&#xff09;安装selenium 二、Selenium使用1、简单使用2、元素定位3、获取元素信息4、交互 三、Phan…...

Linux系统下安装Mysql

1、执行命令&#xff1a;rpm -qa | grep -i mysql&#xff0c;先查看系统之前是否有安装相关的rpm包&#xff0c;如果有&#xff0c;会显示类似下面的信息&#xff1b; 2、通过命令yum -y remove mysql-*  一次性删除系统上所有相关的rpm包&#xff0c;或者通过命令yum -y …...

Jenkins学习笔记1

CI 服务器&#xff1a; 认识Jenkins&#xff1a; Jenkins是一个可扩展的持续集成&#xff08;CI&#xff09;引擎&#xff0c;是一个开源项目&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使得软件持续集成变成可能。Jenkins非常易于安装和配置&#xff0c;简单易…...

注意力机制

概念没什么好说的&#xff0c;反正大家都会说&#xff0c;具体实战怎么写才是最为重要的 1.自注意力 假设有一组数据&#xff0c;都是一维的向量&#xff0c;这个向量可能是一个样本&#xff0c;可能是其他什么&#xff0c;都无所谓。 假设有一组一维向量x1,x2,x3,x4,x5; 第…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...