SpringBoot项目定义Bean常见方式

news2024/11/15 20:03:06

1. spring原生的xml 配置bean 现在几乎淘汰,忽略!!

2. @Component 及其衍生注解 (@Controller、@Service、@Repository)

@Component
public class Cat {
}

3. @Configuration + @Bean

@Configuration
public class AnimalConfig {

    @Bean
    public Dog dog() {
        return new Dog();
    }
}

4. 直接使用@Import

public class Bird {
}

 

  4.1 实现 ImportSelector接口

package com.ldj.springboot.importbean.selector;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.CollectionUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;

/**
 * User: ldj
 * Date: 2024/8/24
 * Time: 23:54
 * Description: No Description
 */
public class MyBeanSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        List<String> springBeanPaths = SpringFactoriesLoader.getSpringBeanPaths("spring.factories");
        if (CollectionUtils.isEmpty(springBeanPaths)) {
            throw new RuntimeException("spring.factories文件 缺少配置!");
        }

        // 这个路径数组你也可以直接写,不需要专门读取配置文件,这里是为了演示springboot读取META-INF 里的spring.factories
        return springBeanPaths.toArray(new String[0]);
    }
}

// 读取要注入容器的类所在路径的配置文件
class SpringFactoriesLoader {
    public static List<String> getSpringBeanPaths(String path) {
        List<String> classPaths = new LinkedList<>();
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        String str;
        try {
            ClassPathResource classPathResource = new ClassPathResource(path);
            inputStream = classPathResource.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream);
            bufferedReader = new BufferedReader(inputStreamReader);
            while ((str = bufferedReader.readLine()) != null) {
                System.out.println(str);
                classPaths.add(str);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return classPaths;
    }

}

  4.2 实现 ImportBeanDefinitionRegistrar 接口

package com.ldj.springboot.importbean.registrar;

import com.ldj.springboot.importbean.config.OrderConfig;
import com.ldj.springboot.importbean.config.UserConfig;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
 * User: ldj
 * Date: 2024/8/24
 * Time: 22:22
 * Description: No Description
 */
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AbstractBeanDefinition userConfigBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(UserConfig.class).getBeanDefinition();
        AbstractBeanDefinition orderConfigBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(OrderConfig.class).getBeanDefinition();

        // 以定义态方式注册到容器
        registry.registerBeanDefinition("userConfig", userConfigBeanDefinition);
        registry.registerBeanDefinition("orderConfig", orderConfigBeanDefinition);
    }

}
package com.ldj.springboot.importbean;

import com.ldj.springboot.importbean.config.*;
import com.ldj.springboot.importbean.registrar.MyBeanDefinitionRegistrar;
import com.ldj.springboot.importbean.selector.MyBeanSelector;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Import;


@SpringBootApplication
@Import(value = {Bird.class, MyBeanSelector.class, MyBeanDefinitionRegistrar.class,})
public class ImportBeanApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ImportBeanApplication.class);
        for (String beanDefinitionName : annotationConfigApplicationContext.getBeanDefinitionNames()) {
            System.out.println("beanDefinitionName: " + beanDefinitionName);
        }

        System.out.println("==========================");

        // @Component
        System.out.println(annotationConfigApplicationContext.getBean(Cat.class));

        // @Configuration + @Bean
        System.out.println(annotationConfigApplicationContext.getBean(Dog.class));

        // @Import
        System.out.println(annotationConfigApplicationContext.getBean(Bird.class));

        // @Import + ImportSelector
        System.out.println(annotationConfigApplicationContext.getBean(UserConfig.class));
        System.out.println(annotationConfigApplicationContext.getBean(OrderConfig.class));

        //  @Import + ImportBeanDefinitionRegistrar --> (beanDefinition)
        System.out.println(annotationConfigApplicationContext.getBean(ProductConfig.class));
        System.out.println(annotationConfigApplicationContext.getBean(StoreConfig.class));

        // BeanFactoryPostProcessor --> (beanDefinition)
        System.out.println(annotationConfigApplicationContext.getBean("carService"));
    }
}

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

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

相关文章

【OpenGL】xcode+glfw画三角形

环境搭建 1. 执行brew install glfw 2. 项目中Build Settings中header Search Paths中添加glfw的include路径 3. 项目中Build Phases中的Link Binary With Libraries中添加glfw的lib文件&#xff08;路径/opt/homebrew/Cellar/glfw/3.4/lib/libglfw.3.4.dylib&#xff09;及…

21.缓存穿透

缓存穿透 客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;这些请求都会到达数据库。会造成数据库宕机。 解决方案 1.缓存空对象 例如查询数据的id&#xff0c;发现数据库中没有&#xff0c;那么就在redis中缓存空对象。但是会有额…

springboot项目读取 resources 目录下的文件的9种方式

1. 使用 ClassLoader.getResourceAsStream() 方法 InputStream inputStream getClass().getClassLoader().getResourceAsStream("file.txt"); 2. 使用 Class.getResourceAsStream() 方法 InputStream inputStream getClass().getResourceAsStream("/file.txt&…

安达发|如何实现陶瓷产业智能化生产计划排单?

随着工业4.0的兴起&#xff0c;智能化生产已成为制造业转型升级的关键。陶瓷产业作为一个历史悠久且技术成熟的行业&#xff0c;面临着生产效率提升和成本控制的双重挑战。智能化生产计划排单作为提高生产效率、降低资源浪费的重要手段&#xff0c;对于陶瓷产业的现代化转型至关…

ElasticSearch 8.15.0 与 Kibana 8.15.0 尝鲜体验

还不算晚&#xff0c;虽然已经距离发布过去了快半个月~ 跟着下面的步骤进行一步一步操作(CV)&#xff0c;只需要改动一下用户名、密码这些数据即可从零开始用 Docker安装 ES 与 Kibana 最新版&#xff0c;据说 Kibana 还有 AI 助手嘞(虽然是 8.12 推出的)~ 最后强调一点&#…

redis | 认识非关系型数据库Redis的列表类型及python如何操作redis

Redis 非关 kv型 数据类型列表常用命令应用场景练习 pyredis 操作redisubuntuwindows 连接redis生产者消费者模型 数据类型 数据类型丰富&#xff0c;字符串strings,散列hashes,列表lists&#xff0c;集合sets,有序集合sorted sets等等 列表 单进程 单线程 尽可能规避掉阻塞的操…

openIM prometheus容器一直重启问题处理

官方文档参考&#xff1a;https://docs.openim.io/zh-Hans/guides/gettingStarted/admin 具体操作&#xff1a; 1、打开 openim-server/config/prometheus.yml 文件&#xff0c;internal_ip改为127.0.0.1&#xff08;内网ip,我的是在本地&#xff09;, 2、第二点说 在 open-i…

我的CSDN-----第128天创作纪念日

机缘 起初的我&#xff0c;是为了在学习代码的过程中通过写博客的方式来巩固自己的知识。后来在遇到不会的问题时可以在csdn上面查找&#xff0c;寻求一点思路&#xff0c;将学到的知识通过博客的方式呈现出来。 收获 每当发布一篇博客后&#xff0c;就会收到很多人的评论加关…

出现Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are requiredProperty报错

目录&#xff1a; bug Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are requiredProperty报错解决方法 bug Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are requiredProperty 报错 在一个springboot demo启动的时候出现以下错误 &#xff0c;…

【前端基础篇】JavaScript之DOM介绍

文章目录 WebAPI背景知识什么是WebAPI什么是APIAPI参考文档 DOM基本概念什么是DOMDOM树查找HTML元素方法概览1. document.getElementById(id)2.document.getElementsByTagName(name)3. document.getElementsByClassName(name)4. document.querySelector(CSS选择器)5. document.…

实习手记(8):增删改查

上周又偷懒了没有按时写博客&#xff08;扣大分啊啊&#xff01;&#xff09;但是好像也没有人看呢~其实最开始也只是想着记录一下实习历程&#xff0c;怕自己之后回过头想关于实习的都想不起来了&#xff0c;个人还是喜欢记录有关自己的学习生活的&#xff0c;就算没啥人看但回…

RabbitMQ 基础总结

一、前言 我们一般的项目过程都是同步通信&#xff0c;及一个服务结束后在执行另一个服务这会让总体时间变得很长&#xff0c;尤其是在高并发的时候用户体验感很不好&#xff0c;且在调用一个服务期间cup内存等都处于空闲状态造成资源浪费 。如果调用其中某一个服务时…

LVS+Keepalived集群(主、备)

1、Keepalived及其工作原理 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用&#xff08;HA&#xff09;方案&#xff0c;可以解决静态路由出现的单点故障问题。 keepalived 高可用之间是通过VRRP进行通信&#xff0c;VRRP是通过竞选的来确定主备&#xff0c;主优先级高…

学习之appium的简单使用

使用之前需要先安装一下依赖 1、安装jdk&#xff1a;暂时为整理笔记以后补充 2、安装nodejs:https://blog.csdn.net/qq_42792477/article/details/141363957?spm1001.2014.3001.5501 3、安装SDk&#xff08;安卓篇&#xff09;&#xff1a;https://blog.csdn.net/qq_42792477…

<数据集>Visdrone数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;8629张 标注数量(xml文件个数)&#xff1a;8629 标注数量(txt文件个数)&#xff1a;8629 标注类别数&#xff1a;10 标注类别名称&#xff1a;[pedestrian,people,bicycle,car,van,truck,tricycle,awning-tricycle…

HubSpot 自动化营销平台助力出海企业精准获客与转化 | 自动化营销

HubSpot 提供了多个开源 cms 和一体化且全面的解决方案&#xff0c;可帮助出海企业优化内容营销策略 HubSpot 自动化营销加速国际化 随着全球化的推进&#xff0c;越来越多的企业开始寻求拓展国际市场&#xff0c;而在这个过程中&#xff0c;有效的客户关系管理和营销自动化成…

ActiveMQ指南

入门 官网&#xff1a; http://activemq.apache.org/ ActiveMQ 是Apache出品&#xff0c;最流行的&#xff0c;能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。 JMS JMS即Java消息服务&#xff08;Java Message Service&#xf…

Linux自旋锁和读写锁

在前面的文章中我们已经介绍了有关互斥锁的概念与使用&#xff0c;本篇将开始介绍在 Linux 中的自旋锁和读写锁。这三种锁分别用于在不同的应用场景之中&#xff0c;其中互斥锁最为常用&#xff0c;但是我们需要了解一下其他的锁。 对于自旋锁和读写锁都介绍了其原理以及接口使…

【信创】麒麟KylinOS V10打开root登录桌面权限

原文链接&#xff1a;【信创】麒麟KylinOS V10打开root登录桌面权限 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在麒麟KYLINOS V10上如何打开root用户登录桌面的文章。在大多数Linux发行版中&#xff0c;出于安全考虑&#xff0c;root用户默认情况下是禁止直…

KRTS网络模块:TCP服务端、客户端实例

KRTS网络模块:TCP服务端、客户端实例 目录 KRTS网络模块:TCP服务端、客户端实例TCP简介KRST服务端简介核心特性界面设计核心代码 KRTS客户端简介核心特性界面设置核心代码 运行实例 Socket模块基于Packet模块&#xff0c;实时提供更高的协议&#xff0c;如RAW-IP、TCP 和 UDP(参…