随笔记录-看nacos源码

news2024/11/17 23:53:18

@Import注解

@Import注解可以导入一些配置类,也就是创建一些指定对象。

使用@Import导入普通类

在这里插入图片描述

项目结构中,import-consumer和import-provider都是同层级的module,import-consumer的pom文件中有引用import-provider的依赖;

import-provider中创建接口的实现类:ImportFirstWayProviderConfig

@Slf4j
public class ImportFirstWayProviderConfig implements ImportAnnotationAble{

    @PostConstruct
    public void init(){
         log.info("这是@Import注解第一种用法,直接导入普通类");
    }

    @Override
    public String introduce() {
        return "这是@Import注解第一种用法,直接导入普通类";
    }
}

import-consumer中创建注解 @TestImportAnnotation

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(value = {ImportFirstWayProviderConfig.class})
public @interface TestImportAnnotation {
}

import-consumer中任意一个@service中使用刚才创建的@TestImportAnnotation注解:

@Service
@TestImportAnnotation
public class ThreeImportService {

}

然后启动 import-consumer module:

在这里插入图片描述

可以发现启动的是import-consumer,但是成功将import-provider中ImportFirstWayProviderConfig类给创建了。

实现ImportSelector接口

在import-provider种,添加一个类: ImportSecondWayProviderConfig

@Slf4j
public class ImportSecondWayProviderConfig implements ImportAnnotationAble{


    @PostConstruct
    public void init(){
        log.info("这是@Import注解【第二种】用法,在消费module里实现ImportSelector接口");
    }

    @Override
    public String introduce() {
        return "这是@Import注解【第二种】用法,在消费module里实现ImportSelector接口";
    }
}

在import-consumer种,实现ImportSelector接口:ImportSecondWayImpl

public class ImportSecondWayImpl implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.example.importProvider.config.importWay.ImportSecondWayProviderConfig"};
    }
}

其中返回的字符串就是 ImportSecondWayProviderConfig 的全路径;在@TestImportAnnotation注解中添加:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(value = {ImportFirstWayProviderConfig.class, ImportSecondWayImpl.class})
public @interface TestImportAnnotation {
}

启动import-consumer项目:

在这里插入图片描述

可以看到也是成功加载了。

实现ImportBeanDefinitionRegistrar接口

在import-provider中添加 ImportThirdWayProvider 类:

@Slf4j
public class ImportThirdWayProvider implements ImportAnnotationAble{

    @PostConstruct
    public void init(){
        log.info("这是@Import注解《第三种》用法,在消费module里实现ImportBeanDefinitionRegistrar接口");
    }

    @Override
    public String introduce() {
        return "这是@Import注解《第三种》用法,在消费module里实现ImportBeanDefinitionRegistrar接口";
    }
}

在import-consumer中实现ImportBeanDefinitionRegistrar接口:

public class ImportThirdWayImpl implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition define = new RootBeanDefinition(ImportThirdWayProvider.class);
        registry.registerBeanDefinition("importThirdWay",define);
    }
}

在RootBeanDefinition的带参构造函数中,参数就是需要的ImportThirdWayProvider 对象,在@TestImportAnnotation注解中添加:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(value = {ImportFirstWayProviderConfig.class, ImportSecondWayImpl.class, ImportThirdWayImpl.class})
public @interface TestImportAnnotation {
}

启动项目:

在这里插入图片描述

@ConditionalOnProperty注解

新建一个注解 @ConditionToday:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@ConditionalOnProperty(value = "today.isWorkDay", matchIfMissing = true)
public @interface ConditionToday {
}

新建一个注解修饰的类:

@Slf4j
@Configuration(proxyBeanMethods = false)
@ConditionToday
public class ConditionWorkBean {

    @PostConstruct
    public void init(){
        log.info("这是 ConditionWorkBean 的 init方法");
    }

}

在application.yml中添加配置:

today:
  isWorkDay: true

在spring.factories文件中增加这个类:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.example.importConsuemer.bean.ConditionWorkBean

成功启动项目:

在这里插入图片描述

修改配置为false,再次启动项目,会发现并没有打印 日志,说明没有创建。

@Bean注解修饰方法

之前一直使用@Bean注解方法修饰无参的方法,在看NacosServiceRegistryAutoConfiguration源码的时候,发现修饰的是有参构造方法,好奇参数的值是怎么创建的。

创建两个普通对象 BeanAnnotationUse ,BeanAnnotationUse :

public class BeanHasCreated {
    private String name;

    public String getName() {
        return name;
    }
}

@Slf4j
public class BeanAnnotationUse {
    private String name;

    public String getName() {
        return name;
    }

    public BeanAnnotationUse(String name) {
        this.name = name;
    }

    public BeanAnnotationUse() {
    }

    public String test(){
        log.info("这是使用@Bean注解创建的bean的测试方法,输出的name={}",getName());
        return getName();
    }
}

再新增一个中间类,TestBeanAnnotation,并将这个类配置再spring.factories中。

@Slf4j
public class TestBeanAnnotation {

    @PostConstruct
    public void init(){
        log.info("这是测试 @Bean注解的初始化方法");
    }

    @Bean
    public BeanAnnotationUse beanAnnotationUse2(BeanHasCreated bhc){
        return new BeanAnnotationUse("@Bean修饰有参数的方法");
    }
}

编译有报错,并且启动项目也会报错,提示的很清楚:找不到BeanHasCreated这个对象,

在这里插入图片描述

@Configuration
public class BeanHasCreated {
    private String name;

    public String getName() {
        return name;
    }
}

在BeanHasCreated类上增加@Configuration注解,这个时候编译没报错,启动项目也正常,那就说明@Bean修饰的方法参数必须是已经在spring中注入过的bean。

ApplicationListener接口和ApplicationEventPublisher接口

ApplicationEventPublisher接口时spring提供的一个用来发布事件的接口,ApplicationListener接口时spring提供的一个用来订阅事件发布的接口。

ApplicationListener接口demo

新建一个订阅事件类:

@Configuration
@Slf4j
public class TestWebServerEventListener implements ApplicationListener<WebServerInitializedEvent> {
    @Override
    public void onApplicationEvent(WebServerInitializedEvent event) {
        log.info("接收的容器启动事件的");
    }
}

然后直接启动项目,会发现打印结果符合预期。

在这里插入图片描述

使用@EventListener注解

在这里插入图片描述

自定义事件和自定义订阅

新建自定义事件对象:

public class TestSelfEvent extends ApplicationEvent {

    private String eventName;

    public TestSelfEvent(Object source) {
        super(source);
        this.eventName = "随便自定义的事件";
    }

    public TestSelfEvent(Object source, Clock clock) {
        super(source, clock);
    }

    @Override
    public String toString() {
        return "TestSelfEvent{" +
                "eventName='" + eventName + '\'' +
                '}';
    }
}

新建发布类:

@Slf4j
@Component
public class TestSelfPublisher implements ApplicationEventPublisher, ApplicationContextAware {

    private ApplicationContext context;

    @Override
    public void publishEvent(Object event) {
        log.info("准备发布一个事件:{}",event.toString());
        context.publishEvent(event);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
}

新建订阅对象:

@Slf4j
@Configuration
public class SelfEventListener implements ApplicationListener<TestSelfEvent> {

    @Override
    public void onApplicationEvent(TestSelfEvent event) {
        log.info("接收到事件,内容是,event.getSource() = {}",event.getSource());
    }

}

再新建一个测试用的类:

@Configuration
@AutoConfigureAfter({TestSelfPublisher.class,SelfEventListener.class})
@Slf4j
public class TestSelfEventImport {


    @Autowired
    private  TestSelfPublisher tsp;

    @PostConstruct
    public void init(){
        TestSelfEvent tsf = new TestSelfEvent("这是一个自定义的随便的任意的一个事件");
        tsp.publishEvent(tsf);
    }

}

启动项目,打印如下:

在这里插入图片描述

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

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

相关文章

baby_web (攻防世界)

前言: 这篇文章还是是为了帮助一些 像我这样的菜鸟 找到简单的题解 题目描述 进入网址 解题工具: 一个有F12的键盘 问题解析: 题目说想想初始页面是哪个 一般都是index.php 然后如题分析即可 科普时间叒到 HTTP状态码 &#xff08;英语&#xff1a;HTTP Status Code…

从零开始操作系统-08:计时器

这一节主要主要是计时器。 所需要的文件在Github&#xff1a;https://github.com/yongkangluo/Ubuntu20.04OS/tree/main/Files/Lec7-ExternalInterrupt 计时器&#xff1a; 可编程间隔计时器&#xff1a;PIT&#xff08;Programmalbe Interval Timer&#xff09;8254 使用A…

Windows下文本生成图像AI画图尝鲜体验

工具库 transformers 的开源方 Hugging Face 发布了一个专注于 diffuser 模型的开源库&#xff0c;我们可以基于它&#xff0c;仅仅通过几行代码就开始生成自己的艺术作画。不过这个 diffuser 库是一个基础实现版本&#xff0c;训练和学习的数据也没有 OpenAI 的 DALL-E2、谷歌…

学习docker记录(三)

使用volume 创建一个数据卷 docker volume create test-first-volume创建完之后&#xff0c;可以在 /var/lib/docker/volumes/ 目录下看见新建了一个 test-first-volume文件夹 在Dockerfile中 volume的指定的目录是&#xff1a; /www/wwwroot/pictureManager/deploy原本以为…

三步教你快速入手一个新产品的测试

初入一家公司&#xff0c;当一个全新的产品摆在你的面前&#xff0c;你会如何快速入手呢&#xff1f; 虽说实践是熟悉系统的第一要素&#xff0c;但我们需要静静思考一下。 我是谁&#xff1a;QA 我在哪&#xff1a;产品组 我要做什么&#xff1a;保质量 有多少来熟悉&…

LeetCode 320 周赛

总结 本场周赛太拉跨了&#xff01;T1做完后&#xff0c;T2一直被卡住&#xff0c;还好后面暂时跳过了T2去做T3&#xff0c;T3做完后又回过头来继续调试T2。在最后10分钟调过了&#xff08;虽然后来看运行时长达到了1400ms&#xff08;差点就过不了&#xff09;&#xff09;。 …

vue3 斗兽棋游戏

近来掘金举办前端比赛&#xff0c;所以写了一个小游戏参加&#xff0c;而且熟悉一下vue3,写了一下游戏&#xff0c;思来想去就写了一个斗兽棋游戏。 欢迎去给我加油 点赞评论收藏 &#xff0c;试玩地址 游戏地址 童年斗兽棋 - 码上掘金 https://code.juejin.cn/pen/716…

四川水泥杂志四川水泥杂志社四川水泥编辑部2022年第11期目录

水泥与混凝土 外加剂含固量对混凝土性能影响的分析 金世鑫; 1-4 《四川水泥》投稿&#xff1a;cnqikantg126.com 粉煤灰在干混砂浆中的应用研究 方光旭;古再努尔依明;杨博;陈南希;张琰琦; 5-7 浅析透光混凝土在建筑空间中的应用 李嘉;李嘉鑫; 8-10 研究与探讨…

c++ 智能指针 shared_ptr

C 智能指针 shared_ptr 详解与示例_码农小明的博客-CSDN博客_shared_ptr 一、简介 shared_ptr 是c11的智能类&#xff0c;可以在任何地方都不使用的时候自动删除和相关指针&#xff0c;从而彻底消除内存泄漏和指针悬空的问题。 她遵循共享所有权&#xff0c;即不同的shared_pt…

CVPR‘15 Joint action recognition and pose estimation from video

任务&#xff1a;action recognition and pose estimation 思路&#xff1a;对动作和姿态进行统一建模&#xff0c;将动作分成姿态&#xff0c;再将姿态分成part&#xff0c;学习三种level特征&#xff0c;通过动态规划有效的推断动作标签和姿态。 方法&#xff1a;统一建模…

通俗理解计算机操作系统的作用

“操作系统”&#xff0c;简称“OS”&#xff0c;是一个包含多个部分和多个目标的大型程序。 它的第一项工作是在你第一次打开计算机时启动并运行计算机。它的另一项工作是启动和结束应用程序&#xff0c;并给每个程序一个运行时间。它是那台计算机上所有其他程序的“老大”。当…

【App自动化测试】(一)Appium和移动端自动化

目录1. 目前mobile自动化解决方案1.1 iOS和Android 测试工具1.2 自动化工具的选择1.3 选择自动化工具的考虑因素2. Appium介绍2.1 Appium介绍2.2 多架构支持2.3 推荐Appium的理由2.4. Appium框架介绍2.4.1 Appium引擎列表2.4.2 Appium设计理念前言&#xff1a; 本文为在霍格沃兹…

多智能体强化学习MARL的概念和框架

1.多智能体强化学习 系统里的agents数量大于1&#xff0c;agents彼此之间不是独立的 每个agent的动作都能影响到下一个状态每个agent都能影响到其他agent 除非agent之间是独立的&#xff0c;否则单一agent的RL方法不适合MARL 2.MARL的类型 Fully cooperative&#xff08;完…

智慧医院智慧医疗解决方案

IBM于2009年提出“智慧医疗”这一理念。作为“智慧的地球”战略的重要组成部分&#xff0c;致力于构建一个“以病人为中心”的医疗服务体系。通过在服务成本、服务质量和服务可及性三方面取得一个良好的平衡&#xff0c;从而优化医疗实践成果、创新医疗服务模式和业务市场&…

Unity插件Obi.Rope详解

前言 Obi.Rope插件的使用方法 绳子的创建 创建后的Obi Rope&#xff0c;Inspector面板如下所示&#xff0c;组件比较多&#xff0c;其中Obi Solver是绳子&#xff0c;布料&#xff0c;液体等的总处理器&#xff0c;也可以单独分出来此组件为一个独立的游戏对象。 绳子的形状…

风控标签体系的使用与介绍

随着大数据技术的深入研究与应用&#xff0c;企业的专注点日益聚焦于怎样利用大数据来为精细化运营及精准营销服务&#xff0c;进而深入挖掘潜在的商业价值。于是&#xff0c;用户画像的概念也就应运而生。 在推荐系统中&#xff0c; 【推荐系统内容&#xff0c;详情可以关注番…

弘玑Cyclone2022产品发布会:全新上线智能文档处理交互平台——尚书台

近日&#xff0c;在弘玑Cyclone“智无边界&#xff0c;数字未来”发布会上&#xff0c;弘玑Cyclone2022年超级自动化系列产品全新亮相&#xff0c;首席产品官贾岿博士带领产品团队以创新技术对新时代语境下的数字生产力进行了全新解读。 上期为大家介绍了人人可用的数字化工作…

Java工具库Guava的数学运算常用方法示例代码

场景 Java核心工具库Guava介绍以及Optional和Preconditions使用进行非空和数据校验&#xff1a; Java核心工具库Guava介绍以及Optional和Preconditions使用进行非空和数据校验_霸道流氓气质的博客-CSDN博客_guava 校验 为什么使用 Guava Math 1、Guava Math 针对各种不常见…

web网页设计期末课程大作业:美食餐饮文化主题网站设计——中华美德6页面HTML+CSS+JavaScript

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

MCE | 表观遗传:YTHDF蛋白调节 m6A-RNA

近期&#xff0c;美国康奈尔大学 Samie R. Jaffrey 研究组在 Cell 上发表了题为 “A Unified Model for the Function of YTHDF Proteins in Regulating m6A-Modified mRNA” 的研究&#xff0c;揭示了 YTHDF 蛋白调节 m6A 修饰的 mRNA 的功能统一模型。与“不同的 m6A 位点结合…