Spring-注解

news2024/11/15 16:34:05

Spring 注解分类

在这里插入图片描述
在这里插入图片描述

Spring 注解驱动模型

Spring 元注解
@Documented
@Retention()
@Target()
// 可以继承相关的属性
@Inherited
@Repeatable()
Spirng 模式注解

@ComponentScan 原理
ClassPathScanningCandidateComponentProvider#findCandidateComponents

public Set<BeanDefinition> findCandidateComponents(String basePackage) {
	if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
		return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
	}
	else {
		return scanCandidateComponents(basePackage);
	}
}
组合注解

比如@RestController,@SpringBootApplication
注解转换为AnnotationAttributes然后进行合并统一

Spring属性别名

显性别名:
在这里插入图片描述
隐式别名:
这个组合注解
继承EnableAutoConfiguration的属性,用隐式别名来表达,也就是直接拿过来不需要改变它的值:
在这里插入图片描述
如果说我们要补充语义,引用某个属性,自己定义新的属性名称来引用父类的:
在这里插入图片描述
举例如果我们要派生这个注解,我们不可能在注解里面写死扫描路径,这个时候就要通过隐式别名来继承注解ComponentScan的属性,这样我们就可以配置scanBasePackages

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@ComponentScan
public @interface MyComponentScan {
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    String scanBasePackages() default "";

}

我们也可以这样:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@ComponentScan
public @interface MyComponentScan {
	// 传递性别名 basePackages -> value value -> scanBasePackages
    @AliasFor(annotation = ComponentScan.class, attribute = "value")
    String scanBasePackages() default "";
}

Spring属性覆盖

注解和原注解出现同名属性的时候会覆盖原注解的属性

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@ComponentScan
public @interface MyComponentScan {
    @AliasFor(annotation = ComponentScan.class, attribute = "value")
    String scanBasePackages() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@MyComponentScan
public @interface MyComponentScan2 {
    // 显示覆盖
    String[] scanBasePackages() default "";
	// 隐式覆盖 
    @AliasFor(attribute = "scanBasePackages")
    String[] packages() default {};
}
@MyComponentScan2(packages = {"com.yong.annotationpkg"})
// packages 覆盖scanBasePackages scanBasePackages覆盖MyComponentScan scanBasePackages scanBasePackages 引用的是ComponentScan

Spring @Enable 模块驱动

在这里插入图片描述
案例1通过@Configration实现

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DemoConfig.class)
public @interface EnableDemo {

}
@Configuration
public class DemoConfig {
    @Bean
    Person person() {
        Person person = new Person();
        person.setName("liy");
        person.setId(11L);
        return person;
    }
}

@EnableDemo
public class EnableAnnotationDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(EnableAnnotationDemo.class);
        context.refresh();
        Person bean = context.getBean(Person.class);
        System.out.println(bean);
    }
}

案例2通过ImportSelector接口实现:

public class DemoImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.yong.annotationpkg.DemoConfig"};
    }
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DemoImportSelector.class)
public @interface EnableDemo {

}
@EnableDemo
public class EnableAnnotationDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(EnableAnnotationDemo.class);
        context.refresh();
        Person bean = context.getBean(Person.class);
        System.out.println(bean);
    }
}

案例3通过

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DemoImportBeanDefinitionRegister.class)
public @interface EnableDemo {

}
public class DemoImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        AnnotatedBeanDefinition annotatedBeanDefinition = new AnnotatedGenericBeanDefinition(DemoConfig.class);
        registry.registerBeanDefinition("demoConfig", annotatedBeanDefinition);
    }
}
Spring 条件注解

在这里插入图片描述

@Configuration
public class ProfileDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(ProfileDemo.class);
        ConfigurableEnvironment environment = context.getEnvironment();
        // 兜底方案
        environment.setDefaultProfiles("odd");
        // 激活方案
        environment.setActiveProfiles("even");
        context.refresh();
        Object odd = context.getBean(Integer.class);
        System.out.println(odd);
        context.close();
    }
    // 激活不同的环境注册不同的Bean
    @Bean
    @Profile("odd")
    public Integer odd() {
        return 2;
    }
    @Bean
    @Profile("even")
    public Integer even() {
        return 1;
    }
}

自定义实现:

public class EvenProfileCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        return environment.acceptsProfiles("even");
    }
}
@Bean
 @Conditional(EvenProfileCondition.class)
 public Integer even() {
     return 1;
 }

ConditionEvaluator#shouldSkip
在这里插入图片描述

参考资料
小马哥核心编程思想

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

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

相关文章

一款高级管理控制面板主题!【送源码】

AdminLTE是一个完全响应的管理模板。基于Bootstrap5框架和JavaScript插件。高度可定制&#xff0c;易于使用。适用于从小型移动设备到大型桌面的多种屏幕分辨率。AdminLTE 是一个基于Bootstrap 3.x的免费高级管理控制面板主题。 https://github.com/almasaeed2010/AdminLTE —…

前端基础入门:静态页面与动态页面的区别

什么是静态页面和动态页面&#xff1f; 通俗的来讲&#xff0c;静态页面是随着HTML代码的生成&#xff0c;页面的内容和显示效果就基本不会发生变化&#xff08;除非修改页面代码&#xff09;&#xff0c;而动态页面&#xff0c;虽然同样页面代码不发生变化&#xff0c;但是其…

如何在中国网上发布文章

随着互联网的迅猛发展&#xff0c;网上发布文章已经成为一种重要的传播方式。而在中国&#xff0c;作为世界上最大的互联网市场&#xff0c;如何在中国网上发布文章成为了许多人关注的焦点。媒介多多网发稿平台作为一个专业的发稿平台&#xff0c;为广大作者提供了很好的发布文…

建议大家少用点儿网站测速工具

春节休息期间明月有接了几个服务器代运维的业务&#xff0c;期间就发现不少新手站长们还在用 17ce、站长工具等等这些网站测速工具来评判站点访问速度的&#xff0c;感觉很有必要给大家聊聊这个事儿&#xff0c;因为这毕竟也是一个涉及服务器安全的一个重要环节了。 其实&#…

Linux系统编程(五)多线程

目录 一、基本知识点二、线程的编译三、 线程相关函数1. 线程的创建2. 线程的退出3. 线程的等待补充 四、综合举例 一、基本知识点 线程&#xff08;Thread&#xff09;是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。一个标准…

Java程序设计

一 Java基础知识 1 Java语言概述 1.1 发展历史 1.2 Java应用领域 Web开发&#xff1a;电子商务网站、内部管理系统、社交网络、门户网站移动开发&#xff1a;Android开发桌面开发&#xff1a;办公软件、游戏、工具软件企业应用开发&#xff1a;客户关系管理、企业资源计划、…

长难句打卡5.29

Today, professors routinely treat the progressive interpretation of history and progressive public policy as the proper subject of study while portraying conservative or classical liberal ideas — such as free markets and self-reliance — as falling outsid…

学习笔记——动态路由协议——OSPF(OSPF网络类型1)

五、OSPF网络类型 网络类型&#xff1a;是指运行OSPF网段的二层链路类型。 1、OSPF网络类型简介 (1) OSPF网络类型 MA(Multi-Access &#xff0c;多路访问)在一个网段内的节点数量不限制(一条链路上有多个访问点)。MA的网络一般分为两种&#xff1a; 1)广播式多路访问网络…

vue3学习(四)

前言 接上篇学习笔记&#xff0c;分享3个内置组件&#xff1a;动态组件、缓存组件、分发组件基本用法。大家一起通过code的示例&#xff0c;从现象理解,注意再次理解生命周期。 一、code示例 组件A&#xff1a;CompA <script setup> import {onMounted, onUnmounted} f…

市场巨变,移动开发行业即将迎来“第二春”?

随着鸿蒙生态的不断壮大&#xff0c;越来越多的企业开始加入其中&#xff0c;对鸿蒙OS开发工程师的需求也越来越迫切。 年初时还只有200个APP宣布加入鸿蒙生态&#xff0c;而最近华为也已经官宣&#xff0c;已经有4000多个应用加入鸿蒙&#xff0c;短短三个月就增加了20倍。 …

.NET 直连SAP HANA数据库

前言 上个项目碰到的需求&#xff0c;IT部门要求直连SAP的HANA数据库&#xff0c;以只读的权限读取SAP部门开发的CDS视图&#xff0c;是个有点复杂的工程&#xff0c;需要从成品一直往前追溯到原材料的产地&#xff0c;和交货单、工单、采购订单有相当程度上的关联 IT部门要求…

MySQL的安全性

给root用户设置密码 点击用户--下面三个账号双击--进行编辑 修改密码--修改完进行保存 关闭数据库后连接不上 重新编辑&#xff0c;设置密码 新建账号 填入信息--保存&#xff08;主机哪里要选择%&#xff09; 连接这个新的账号 点击连接--填写连接的名称&#xff0c;地址&…

使用moquette mqtt发布wss服务

文章目录 概要一、制作的ssl证书二、配置wss小结 概要 moquette是一款不错的开源mqtt中间件&#xff0c;github地址&#xff1a;https://github.com/moquette-io/moquette。我们在发布mqtt服务的同时&#xff0c;是可以提供websocket服务器的&#xff0c;有些场景下需要用到&a…

多激光雷达ip与端口配置

首先是雷达的ip 我们连上雷达&#xff0c;想要进入雷达的上位机的时候&#xff0c;需要对本机ip进行一些配置&#xff1a; 第一个是ip&#xff0c;第二个是掩码&#xff0c;第三个是网关。 其中ip可以通过wireshark来进行读取&#xff0c;一般就是192.168.102(雷达默认) 然后掩…

一种基于高德Web API实现沿路画面的实现

概述 本文在mapboxGL框架下&#xff0c;分享一种基于高德Web API实现沿路画面的实现。 实现效果 实现 1. 实现思路 通过点击获取路径的起点和终点&#xff1b;将多次规划路径的结果连成一条线&#xff1b;当鼠标点击回到第一个点的时候结束绘制&#xff1b;绘制结束后将路径…

Linux: network: tcp spurious retrans 的一个原因

最近分析问题的时候&#xff0c;从wireshark里看有&#xff1a;tcp spurious retrans 的包&#xff0c;309这个是307 的retransmission&#xff0c;而且在308 回复了ACK。那为什么会重传&#xff1f; 从网上找了一些&#xff0c;比如 https://www.packetsafari.com/blog/2021…

# 解决 win11 连接共享打印机,报错 0x00000709 问题

解决 win11 连接共享打印机&#xff0c;报错 0x00000709 问题 一、问题描述&#xff1a; 当我们连接一台共享打印机&#xff0c;出现报错 0x00000709 时&#xff0c;这是由于本机注册表本配置 RPC 远程调用&#xff0c;我们需要对自己的电脑进行修改&#xff0c;而不是主机&a…

3DEXPERIENCE DELMIA Role: RVN - Robotics Virtual Commissioning Analyst

Discipline: Robotics Role: RVN - Robotics Virtual Commissioning Analyst 通过准确地模拟连接到PLC程序的机器人、设备和传感器&#xff0c;在制造虚拟孪生上执行虚拟调试情景 为任何机器人角色的多周期情景创建传感器&#xff0c;生成和变换零件启用 PLC 程序的虚拟验证和…

【C语言习题】25.求两个数二进制中不同位的个数

文章目录 作业标题作业内容2.解题思路3.具体代码4.代码讲解 作业标题 求两个数二进制中不同位的个数 作业内容 编程实现&#xff1a;两个int&#xff08;32位&#xff09;整数m和n的二进制表达中&#xff0c;有多少个位(bit)不同&#xff1f; 输入例子: 1999 2299 输出例…

算法——链表

一、重新排队——蓝桥杯3255 1.2题解 思路 对1-n的数字进行m次操作得到的结果&#xff08;每次移动的是x&#xff09; 代码 #include <iostream> using namespace std; int main() {// 请在此输入您的代码int n,m;cin>>n>>m;int i1;int a[m][3];for(i;i…