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

11Spring IoC注解式开发(上)(元注解/声明Bean的注解/注解的使用/负责实例化Bean的注解)

注解的存在主要是为了简化XML的配置。Spring6倡导全注解开发。
注解开发的优点:提高开发效率
注解开发的缺点:在一定程度上违背了OCP原则,使用注解的开发的前提是需求比较固定,变动较小。

1 注解的注解称为元注解

自定义一个注解:

package com.sunsplanter.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(value = {ElementType.TYPE,ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Component {String value();
}
  • 该注解上面修饰的注解包括:Target注解和Retention注解,这两个注解被称为元注解。
  • Target注解用来设置Component注解可以出现的位置,以上代表表示Component注解只能用在类和接口上。
  • Retention注解用来设置Component注解的保持性策略.
    SOURCE:注解只被保留在Java源文件中,class文件不包含注解.
    CLASS:注解最终被保留到class文件中,但不能被反射机制读取.
    RUNTIME:注解最终被保留到class文件中,并且可以被反射机制读取.

String value(); 是Component注解中的一个属性。该属性类型String,属性名是value。

2 管中窥豹注解的作用-通过反射机制读取注解

目标:只知道报包名:com.sunsplanter.bean,至于这个包下有多少个Bean我们不知道。哪些Bean上有注解,都不知道.
通过程序全自动化判断: 若Bean类上有Component注解时,则实例化Bean对象,如果没有,则不实例化对象。

我们准备两个Bean,一个上面有注解,一个上面没有注解。

package com.sunsplanter.bean;import com.sunsplanter.annotation.Component;@Component("userBean")
public class User {
}
package com.sunsplanter.bean;public class Vip {
}
package com.sunsplanter.test;import com.sunsplanter.annotation.Component;import java.io.File;
import java.net.URL;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;public class Test {public static void main(String[] args) throws Exception {// 存放Bean的Map集合。key存储beanId。value存储Bean。Map<String,Object> beanMap = new HashMap<>();String packageName = "com.sunsplanter.bean";//将com.sunsplanter.bean转化成com/sunsplanter/bean并存到path中String path = packageName.replaceAll("\\.", "/");//获取这个包在系统中的绝对路径:file:/D:/study/spring6/spring6-005-Annotation/target/classes/com/sunsplanter/beanURL url = ClassLoader.getSystemClassLoader().getResource(path);//获取一个绝对路径下的所有子文件,并写入文件数组File file = new File(url.getPath());File[] files = file.listFiles();Arrays.stream(files).forEach(f -> {//获取两个类的相对包路径,如com.sunspalnter.bean.User...String className = packageName + "." + f.getName().split("\\.")[0];try {Class<?> clazz = Class.forName(className);if (clazz.isAnnotationPresent(Component.class)) {Component component = clazz.getAnnotation(Component.class);String beanId = component.value();Object bean = clazz.newInstance();beanMap.put(beanId, bean);}} catch (Exception e) {e.printStackTrace();}});System.out.println(beanMap);}
}

3 声明Bean的注解

通过注解声明该类是一个bean类,今后就会被自动创建bean对象.

负责声明Bean的注解,常见的包括四个:

  • @Component
  • @Controller
  • @Service
  • @Repository

通过源码可以看到,@Controller、@Service、@Repository这三个注解都是@Component注解的别名。
也就是说:这四个注解的功能都一样, 只是为了增强程序的可读性,建议:

● 控制器类上使用:Controller(主要用于给前端返回数据的以及接收前端的数据的)
● service类上使用:Service(处理数据用的)
● dao类上使用:Repository
他们都是只有一个value属性。value属性用来指定bean的id,也就是bean的名字。
在这里插入图片描述

4 Spring注解的使用

如果使用以上的注解, 就不必再每一个类都使用一个bean标签管理. 如何使用以上的注解呢?
● 第一步:加入aop的依赖
● 第二步:在配置文件中添加context命名空间
● 第三步:在配置文件中指定扫描的包
● 第四步:在Bean类上使用注解

第一步:加入aop的依赖
当加入spring-context依赖之后,会关联加入aop的依赖。所以这一步不用做。

第二步:在配置文件中添加context命名空间, 分别是xmlns:context和xsi:schemeLocation

<?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/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>

第三步:在配置文件中指定要扫描的包

<?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/context http://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.sunsplanter.bean"/>
</beans>

第四步:在Bean类上使用注解

package com.sunsplanter.bean;import org.springframework.stereotype.Component;@Component(value = "userBean")
public class User {
}

第四步要小心, 存在两个两个Component
在这里插入图片描述
第二个时上面学习时自己建的,一定要选第一个.

第五步:编写测试程序

package com.sunsplanter.test;import com.sunsplanter.bean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class AnnotationTest {@Testpublic void testBean(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User userBean = applicationContext.getBean("userBean", User.class);System.out.println(userBean);}
}

成功输出一个对象.

如果注解的属性名是value,那么value是可以省略的。
例如:

package com.sunsplanter.bean;import org.springframework.stereotype.Component;@Component("userBean")
public class User {
}
package com.sunsplanter.test;import com.sunsplanter.bean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class AnnotationTest {@Testpublic void testBean(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User userBean = applicationContext.getBean("userBean", User.class);System.out.println(userBean);}
}

仍能输出一个User对象.

甚至: 如果把value属性彻底去掉,该类在被创建成bean时会被自动指定一个bean id(名字), 默认名字的规律是:Bean类名首字母小写即可。

多个包需要扫描的情况
办法1(常用): 指定需要扫描的多个包的共同父包,扫描这个共同父包. 缺点是如果父包有不需要扫描的包,则会牺牲一些效率.
办法2: 逗号分隔多个需要扫描的包:

    <context:component-scan base-package="com.sunsplanter.bean,com.sunsplanter.dao"/>

5 根据注解类型选择性实例化Bean

假设在某个包下有很多Bean,有的Bean上标注了Component,有的标注了Controller,有的标注了Service,有的标注了Repository.
目标: 现在由于某种特殊业务的需要,只允许其中所有的Controller参与Bean管理,其他的都不实例化。

这里为了方便,将这几个类都定义到同一个java源文件中了:

package com.sunsplanter.spring6.bean3;import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;@Component
public class Selective_Instantiation_of_Objects{public Selective_Instantiation_of_Objects() {System.out.println("A的无参数构造方法执行");}
}@Controller
class B {public B() {System.out.println("B的无参数构造方法执行");}
}@Service
class C {public C() {System.out.println("C的无参数构造方法执行");}
}@Repository
class D {public D() {System.out.println("D的无参数构造方法执行");}
}@Controller
class E {public E() {System.out.println("E的无参数构造方法执行");}
}
<?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/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--
use-default-filters="true" 表示:使用spring默认的规则,只要有Component、Controller、Service、Repository中的任意一个注解标注,则进行实例化。
use-default-filters="false" 表示:不再spring默认实例化规则,即使有Component、Controller、Service、Repository这些注解标注,也不再实例化。
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 表示只有Controller进行实例化。--><context:component-scan base-package="com.sunsplanter.bean" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan></beans>

测试程序:

@Test
public void testChoose(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-choose.xml");
}

输出注解为@Controller的B,E构造方法执行.

目标: 现在由于某种特殊业务的需要,除了@Controller外的所有注解都参与Bean管理,仅Controller实例化。

<!--
use-default-filters="true" 表示:使用spring默认的规则,只要有Component、Controller、Service、Repository中的任意一个注解标注,则进行实例化。(不写默认是true)
use-default-filters="false" 表示:不再spring默认实例化规则,即使有Component、Controller、Service、Repository这些注解标注,也不再实例化。
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 表示将Controller排除出实例化的范围。--><context:component-scan base-package="com.sunsplanter.bean"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>

相关文章:

11Spring IoC注解式开发(上)(元注解/声明Bean的注解/注解的使用/负责实例化Bean的注解)

注解的存在主要是为了简化XML的配置。Spring6倡导全注解开发。 注解开发的优点:提高开发效率 注解开发的缺点:在一定程度上违背了OCP原则&#xff0c;使用注解的开发的前提是需求比较固定&#xff0c;变动较小。 1 注解的注解称为元注解 自定义一个注解: package com.sunspl…...

k8s 部署Jenkins项目

1、基于helm 部署jenkins 要求&#xff1a;当前集群配置了storageClass&#xff0c;并已指定默认的storageClass&#xff0c;一般情况下&#xff0c;创建的storageClass即为默认类 指定默认storageClass的方式 # 如果是新创建默认类&#xff1a; apiVersion: storage.k8s.io/v1…...

#每日一题#力扣#2085.统计出现过一次的公共字符串

给你两个字符串数组 words1 和 words2 &#xff0c;请你返回在两个字符串数组中 都恰好出现一次 的字符串的数目。 示例 1&#xff1a; 输入&#xff1a;words1 [“leetcode”,“is”,“amazing”,“as”,“is”], words2 [“amazing”,“leetcode”,“is”] 输出&#xff1a;…...

Python系列(1):简洁优雅,功能强大的编程语言

Python&#xff1a;简洁优雅&#xff0c;功能强大的编程语言 一、Python的特点二、Python的应用领域 在当今的编程世界中&#xff0c;Python已经成为了一种无处不在的语言。它不仅简单易学&#xff0c;而且功能强大&#xff0c;支持多种编程范式&#xff0c;包括面向对象编程、…...

HarmonyOS应用开发学习笔记 arkTS自定义弹窗(CustomDialog)简单使用 arkTS弹出框回调、监听

HarmonyOS应用开发学习笔记 arkTS自定义弹窗&#xff08;CustomDialog&#xff09;简单使用 1、CustomDialog装饰器用于装饰自定义弹框 1、定义弹出框 CustomDialog CustomDialog export struct CustomDialogExample {controller: CustomDialogControllerbuild() {Column() {…...

RabbitMQ(六)消息的持久化

目录 一、简介1.1 定义1.2 消息丢失的场景 二、交换机的持久化方式一&#xff1a;直接 new方式二&#xff1a;channel.exchangeDeclare()方式三&#xff1a;ExchangeBuilder【推荐】 三、队列的持久化方式一&#xff1a;直接 new方式二&#xff1a;channel.queueDeclare()方式三…...

mybatisplus配置

一、新建项目&#xff1a;com.saas.plusdemo 二、配置pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sch…...

node-sass@4.7.2 postinstall: `node scripts/build.js`

Can‘t find Python executable “D:\Python36\python.EXE“, you can set the PYTHON env variable.-CSDN博客 gyp ERR! build error gyp ERR! stack Error: C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe failed with exit code: 1 gyp ERR! stack at Chil…...

pyDAL一个python的ORM(9) pyDAL的嵌套查询

假设有以下两个表&#xff1a; db.define_table(person,Field(id, string), Field(‘name, string), Field(‘dept, string)) db.define_table(things,Field(id, string), Field(‘name, string), Field(‘owner, string)) 一、使用belongs进行嵌套查询 我们查询要求&#…...

融资项目——EasyExcel操作Excel文件

EasyExcel是Alibaba集团开源的EasyExcel技术&#xff0c;该技术是针对Apache POI技术的封装和优化&#xff0c;主要解决了POI技术的耗内存问题&#xff0c;并且提供了较好的API使用。不需要大量的代码就可以实现excel的操作功能。 1.EasyExcel的配置 首先引入依赖&#xff0c;…...

OAI openair3-NAS-UE-EMM代码解读(续)

文件路径openair3/NAS/UE/EMM/emm_main.c 714行之后 1.名称&#xff1a;emm_min_get_registered_plmn&#xff08;&#xff09; 获取当前注册PLMN的标识&#xff1b; 输入&#xff1a;format&#xff1a;PLMN标识符的字符串表示的请求格式&#xff1b; 输出&#xf…...

SQL-条件查询与聚合函数的使用

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…...

Qt移植曲线显示

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、确定文件组成&#xff1f;1. 复制新文件2.新建ui窗口 二、实际操作2.1 新建Ui窗口&#xff0c;要添加带.h的否则跳转错误2.2添加文件到.h2.3 添加文件cpp 三…...

基于springboot生鲜交易系统源码和论文

首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包括软件架构模式、整体功能模块、数据库设计。本项…...

vue中鼠标拖动触发滚动条的移动

前言 在做后端管理系统中&#xff0c;像弹窗或大的表单时&#xff0c;经常会有滚动条的出现&#xff0c;但有些时候如流程、图片等操作时&#xff0c;仅仅使用鼠标拖动滚动条操作不太方便&#xff0c;如果使用鼠标拖拽图片或容器来触发滚动条的移动就比较方便了 功能设计 如…...

1、理解Transformer:革新自然语言处理的模型

目录 一、论文题目 二、背景与动机 三、卖点与创新 四、解决的问题 五、具体实现细节 0. Transformer 架构的主要组件 1. 注意力、自注意力&#xff08;Self-Attention&#xff09;到多头注意力&#xff08;Multi-Head Attention&#xff09; 注意力到底是做什么的&…...

Acwing847 图中点的层次(bfs)

这道题用的是bfs&#xff0c;一开始用了dfs搜出了答案为4 题目 给定一个 n个点 m 条边的有向图&#xff0c;图中可能存在重边和自环。 所有边的长度都是 1&#xff0c;点的编号为 1∼n。 请你求出 1 号点到 n 号点的最短距离&#xff0c;如果从 1 号点无法走到 n 号点&…...

windows11通过虚拟机安装Ubuntu20.04

VMware 分为 VMware Workstation Pro 和 VMware Workstation Player, Pro体验期后收费&#xff0c;Player则免费。player 早期不能创建虚拟机&#xff0c;只能Pro创建好后给Player运行&#xff0c;而现在player早已加入创建虚拟机功能&#xff0c;所以使用体验上两者相差不大&a…...

时序预测 | Matlab实现EEMD-SSA-BiLSTM、EEMD-BiLSTM、SSA-BiLSTM、BiLSTM时序预测对比

时序预测 | Matlab实现EEMD-SSA-BiLSTM、EEMD-BiLSTM、SSA-BiLSTM、BiLSTM时间序列预测对比 目录 时序预测 | Matlab实现EEMD-SSA-BiLSTM、EEMD-BiLSTM、SSA-BiLSTM、BiLSTM时间序列预测对比预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现EEMD-SSA-BiLSTM、…...

Android14之解决Pixel手机联网出现感叹号(一百八十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

安卓基础(aar)

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

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...