spring之IoC注解

news2024/12/23 18:30:48

文章目录

  • 前言
  • 一、回顾注解
    • 1、注解怎么定义
    • 2、注解怎么使用
    • 3、通过反射机制怎么读取注解
  • 二、Spring IoC注解式开发原理
    • 1、扫描程序
    • 2、通过反射机制解析注解
    • 3、实例化对象
  • 三、声明Bean的注解


前言

注解的存在主要是为了简化XML的配置


一、回顾注解

1、注解怎么定义

定义一个注解Component
在这里插入图片描述

@Target()//标注注解的注解 叫做元注解。
@Target注解用来修饰@Component可以出现的位置
@Target(value = {ElementType.TYPE,ElementType.FIELD}):用来表示@Component注解可以出现在类上,属性上。
使用某个注解的时候,如果注解的属性名是value的话,value可以省略
即:@Target({ElementType.TYPE,ElementType.FIELD})
使用某个注解的时候,如果注解的属性值是数组,并且数组中只有一个元素,大括号可以省略。
即:@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
也是一个元注解,用来标注@Component注解最终保留在class文件中,并且可以被反射机制读取。

在这里插入图片描述

Override源文件
@Retention(RetentionPolicy.SOURCE) 也就是说@Override这个注解只保留在源文件当中,当这个文件编译生成class文件之后,@Override这个注解就没了

注解的属性

    //定义注解的属性
    //String是属性类型
    //value是属性名
    String value();

    //其他的属性
    //String是属性类型
    //name是属性名
    //String name();

    //数组属性
    //String[] 是属性类型
    //names是属性名
    //String[] names();

完整的代码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
    String value();
}

2、注解怎么使用

@Component(属性名=属性值,属性名=属性值,属性名=属性值……)

创建一个User类使用@Component注解

//@Component(value = "UserBean")
//如果属性名是value ,value可以省略
@Component("UserBean")
public class User {
}

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

public class ReflectAnnotationTest {
    public static void main(String[] args) throws Exception {
        //通过反射机制读取注解
        //1、获取类
        Class<?> clazz = Class.forName("com.powernode.bean.User");
        //2、获取类上的注解
        //2.1、判断类上有没有这个注解
        if(clazz.isAnnotationPresent(Component.class)){
            //2.2、获取注解
            Component annotation = clazz.getAnnotation(Component.class);
            //2.3、访问注解的属性
            System.out.println(annotation.value());
        }
    }
}

运行结果:
在这里插入图片描述

二、Spring IoC注解式开发原理

需求:目前只知道一个包的名字,扫描这个包下所有的类,当这个类上有@Component注解的时候,实例化该对象,然后放入Map集合当中

1、扫描程序

扫描程序:

1、先把目录改为路径
String packageName = “com.powernode.bean”;
String packagePath = packageName.replaceAll(“\.”,“/”);
在这里插入图片描述
2、获取绝对路径
com是在类的根路径下的一个目录
URL url = ClassLoader.getSystemClassLoader().getResource(packagePath);
String path = url.getPath();
在这里插入图片描述
3、获取绝对路径下的所有文件
File file = new File(path);
File[] files = file.listFiles();
Arrays.stream(files).forEach(f->{
System.out.println(f.getName());
});
在这里插入图片描述
System.out.println(f.getName().split(“\.”)[0]);
在这里插入图片描述
4、拼接类名
String className = packageName + “.” + f.getName().split(“\.”)[0];
在这里插入图片描述

2、通过反射机制解析注解

通过反射机制解析注解:
1.3通过反射机制读取注解

3、实例化对象

实例化对象
Object obj = aClass.newInstance();
在这里插入图片描述
Vip类中没有@Component注解,所以没有创建对象

完整代码:

public class ComponentScan {
    public static void main(String[] args) throws  Exception{
        String packageName = "com.powernode.bean";
        //开始写扫描程序
        //先把目录改为路径。 这个.在正则表达式中表示任意字符,
        //在正则表达式中怎么表示一个普通的“.” 使用"\." 在Java语言中“\\.”
        String packagePath = packageName.replaceAll("\\.","/");
        //System.out.println(packagePath);
        //com是在类的根路径下的一个目录
        URL url = ClassLoader.getSystemClassLoader().getResource(packagePath);
        String path = url.getPath();
        //System.out.println(path);
        File file = new File(path);
        File[] files = file.listFiles();
        Arrays.stream(files).forEach(f->{
            try {
                //System.out.println(f.getName());
                //System.out.println(f.getName().split("\\.")[0]);
                String className = packageName + "." + f.getName().split("\\.")[0];
                Class<?> aClass = Class.forName(className);
                if (aClass.isAnnotationPresent(Component.class)) {
                    //获取注解
                    Component annotation = aClass.getAnnotation(Component.class);
                    String id = annotation.value();
                    //有这个注解的都要创建对象
                    Object obj = aClass.newInstance();
                    System.out.println(obj);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        });
    }
}

三、声明Bean的注解

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

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

@Component源码在这里插入图片描述
@Controller源码
是Component是别名
在这里插入图片描述
@Service
是Component是别名
在这里插入图片描述
@Repository
是Component是别名
在这里插入图片描述
是为了增强程序的可读性,建议
持久层(Dao)用@Repository
业务层(Service)用@Service
表示层(Web)用@Controller


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

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

相关文章

c语言操作符(上)

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言初阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>: 讲解c语言中有关操作符的知识. 金句分享: 最慢的步伐…

Python读取sqlite3数据库中的数据

文章目录1. 简介1.1. 使用1.1.1. 创建1.1.2. 插入1.1.2.1. 插入一条数据1.1.3. 查询1.1.3.1. 查询所有数据查询一条数据1.1.3.2. 读取特定位置的数据1.1.4. 修改数据1.1.5. 删除数据1. 简介 从Python3.x版本开始&#xff0c;在标准库中已经内置了SQLlite3模块&#xff0c;它可…

Redis中的哨兵机制

有了主从复制的实现以后,我们如果想对主从服务器进行监控,那么在redis2.6以后提供了一个 “哨兵” 的机制,在2.6版本中的哨兵为1.0版本,并不稳定,会出现各种各样的向题,在2.8以后的版本哨兵功能才稳定起来。 顾名思义,哨兵的含义就是监控Redis系统的运行状况。其主要功…

STM32/51单片机实训day6——Proteus8.6版本+ STM32F103驱动LCD12864显示Keil5程序设计

内 容&#xff1a;实现LCD显示 学 时&#xff1a;4学时 知识点&#xff1a;LCD12864芯片介绍&#xff0c;读写操作时序&#xff0c;电路设计 重点&#xff1a; 读写操作时序 难点&#xff1a;读写操作时序 时间&#xff1a;2022年12月26日 9:00&#xff5e;11:50 总结&…

全国产龙芯2K0500多功能SoC处理器及其解决方案

龙芯2K0500片内集成单个64位龙架构(LoongArch)LA264处理器核、32KB一级指令缓存、32KB一级数据缓存、512KB二级缓存、32位DDR2/3-1066控制器、2DGPU图形核心、DVO显示接口、两路PCIe2.0、两路SATA2.0、四路USB2.0、一路USB3.0、两路GMAC、PCI总线、彩色黑白打印接口、HDA及其他…

有备无患!DBS高性价比方案助力富途证券备份上云

“某中心受病毒攻击&#xff0c;导致服务中断&#xff0c;线上业务被迫暂停” “某公司员工误操作删库&#xff0c;核心业务数据部分丢失&#xff0c;无法完全找回” “由于服务器断线&#xff0c;某医院信息系统瘫痪近4小时&#xff0c;期间病人无法使用医保卡挂号和结算” …

Talk预告 | 微软高级研究员杨征元:统一的视觉语言模型

本期为TechBeat人工智能社区第467期线上Talk&#xff01; 北京时间12月29日(周四)20:00&#xff0c;微软高级研究员——杨征元的Talk将准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “统一的视觉语言模型”&#xff0c;届时将从一个统一的角度概述视觉语…

深度循环神经网络

在深度循环神经网络中&#xff0c;隐状态的信息被传递到当前层的下一时间步和下一层的当前时间步。 有许多不同风格的深度循环神经网络&#xff0c; 如长短期记忆网络、门控循环单元、或经典循环神经网络。 这些模型在深度学习框架的高级API中都有涵盖。 总体而言&#xff0c…

第三方库react-redux基础使用 容器UI组件使用 数据管理优化

其实redux并不是React特有的技术 redux是一家独立公司 做出来 适配与目前几大前端主流框架的状态管理工具。 其实 最初 redux也希望码友们用它来管理vue的状态数据 但后面 React官方发现 很多人喜欢在React项目中使用redux 于是 React公司专门做了react-redux这个第三方的库 帮…

【计组】数据通路和流水线设计--《深入浅出计算机组成原理》(三)

课程链接&#xff1a;深入浅出计算机组成原理_组成原理_计算机基础-极客时间 目录 一、建立数据通路 &#xff08;一&#xff09;组合逻辑电路 1、指令周期 2、数据通路 3、CPU所需硬件电路 &#xff08;二&#xff09;时序逻辑电路 1、时序逻辑电路可以解决的问题 二…

Python爬虫进行正则数据解析实战

今天继续给大家介绍Python爬虫相关知识&#xff0c;本文主要内容是Python爬虫进行正则数据解析实战。 一、需求分析 今天&#xff0c;我们尝试使用re正则表达式来对爬取到的页面进行数据解析。需求如下&#xff1a; 针对网页&#xff1a;https://blog.csdn.net/weixin_402282…

第三十二章 数论——组合数详解(1)

第三十二章 数论——组合数的多种求法一、数学基础二、组合数——递推公式1、题目2、思路3、代码三、组合数——快速幂1、问题&#xff1a;2、分析一、数学基础 组合数来自于高中排列组合的知识&#xff1a; 我们从aaa个小球中随机一次性取出bbb个&#xff0c;所有的取法记作…

Numpy学习记录

numpy.ma.ravel 返回一个连续的扁平数组。 参考&#xff1a; numpy中的ravel()方法使用介绍https://blog.csdn.net/weixin_44025103/article/details/125062287 Python numpy.ravel函数方法的使用https://www.cjavapy.com/article/870/ numpy.meshgrid 二维坐标系中,X轴…

图片如何批量重命名?一步一步教会你

爱拍照的小伙伴应该都知道&#xff0c;无论是手机还是相机拍出来的照片&#xff0c;导入电脑后&#xff0c;它的默认名称都是一串长长的字符。不仅让桌面看起来杂乱无章&#xff0c;还会给我们在查找图片时带来诸多的不便。其实我们可以通过软件对这些图片进行批量重命名的&…

线性代数基础----矩阵

秩的理解: 举证的秩的理解: 特征值和特征向量 线性相关和线性无关 向量的拉伸和旋转: 特征值和特征向量: 特征值: 特征向量: 用来描述矩阵的信息 特征向量 和 特征值之间的关系 拳击:方向和力量 特征值和特征向量的物理意义: 表示相关的重要性 特征值和特征向量:进行提…

阳了在家没事干?教大家用python在家做一个万能看视频软件,绝对正经啦~

嗨害大家好鸭&#xff01;我是小熊猫~ 我前阵子不小心阳了&#xff0c;该说不说&#xff0c;真挺难受的 我在家真的就是纸巾热水不离手&#xff0c; 楼下水果店老板娘还说我年轻人身体怎么这么差… 哼我阳过之后我就锻炼去&#xff01;&#xff01;&#xff01; 效果展示 有…

如何删除掉设备和驱动器下百度网盘的图标

电脑安装百度网盘后&#xff0c;在设备和驱动器这里会有百度网盘的图标&#xff0c;如下图所示。 对有强迫症的人来说&#xff0c;这很难受&#xff0c;就一定要想办法删除掉该图标&#xff0c;那么具体怎么操作呢&#xff1f; 你如果在设备和驱动器下右击百度网盘&#xff0c…

12月小报|读小报,涨知识

本期知识小集的主要内容包括&#xff1a;• Flutter桥调用请注意结果反馈• Flutter await代码带来的潜在并发• Flutter FPS 高不代表一定流畅• Flutter新渲染引擎impeller尝鲜Flutter桥调用请注意结果反馈通过桥来拓展Flutter的能力&#xff0c;是非常通用的Flutter开发场景…

Weda创建视图表格

这边我们先创建一个数据集。 在更多操作里面分布这个数据集。 点击编辑&#xff0c;选择视图配置。 在下面这个界面&#xff0c;新建视图。 在操作里面&#xff0c;点击更多&#xff0c;发布这个视图。 我们点击编辑设置视图的第一行&#xff08;表列设置&#xff09;。 点击…

马上又是新的一年了 “跨年倒计时”送给大家

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;跨年倒计时 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xff0c;欢迎你的加入: 林在闪闪发光的…