springboot加载注入bean的方式

news2024/12/23 12:34:58

在SpringBoot的大环境下,基本上很少使用之前的xml配置Bean,主要是因为这种方式不好维护而且也不够方便。
springboto注入bean主要采用下图几种方式,分为本地服务工程注解声明的bean和外部依赖包中的bean。
在这里插入图片描述

一、 springboot装配本地服务工程中的bean

1、注解装配Bean

1、使用Component,Service,Controller,Repository等派生注解
只要在类上加类上加 @Component 注解即可,该注解只要被扫描到就会注入到spring的bean容器中。

@Component
public class AnoDemoBean {
}

当然不只是@Component注解可以声明Bean,还有如:@Repository、@Service、@Controller 等常用注解同样可以。

如果去看这些注解,就发现这些注解上本身就有加 @Component 注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component   //可以看到@Service注解上有添加@Component,  @Repository和@Controller也一样。        
public @interface Service {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

这系列注解的出现,给我们带来了极大的便利。我们不需要像以前那样在bean.xml文件中配置bean了,现在只用在类上加上相关注解,就能轻松完成bean的定义。

这四种注解在功能上其实没有特别的区别,不过在业界有个不成文的约定:

  • Controller 一般用在控制层
  • Service 一般用在业务层
  • Repository 一般用在数据层
  • Component 一般用在公共组件上

2、@Bean定义方式

这种方式,主要是结合Configuration来定义bean,首先是声明一个配置类,而后再配置类中,经过返回bean对象的方法形式来声明bean,通常使用姿式以下

@Data
public class ConfigDemoBean {
}

@Configuration
public class BeanLoadConfig {
    @Bean
    public ConfigDemoBean configDemoBean() {
        return new ConfigDemoBean();
    }
}

须要说明的一点是BeanLoadConfig类自己也被Spring容器看为一个Bean。

3、Component注解 VS Bean注解

1)作用对象不同:@Component 注解作用于类,而 @Bean 注解作用于方法。

@Bean 方式更加灵活,比如当我们引用第三方库中的类需要装配到 Spring 容器时,只能通过 @Bean 来实现。

比如

@Configuration
public class WireThirdLibClass {
    @Bean
    public ThirdLibClass getThirdLibClass() {
        //第三方的ThirdLibClass类
        return new ThirdLibClass();
    }
}

再比如

@Bean
public OneService getService(status) {
    case (status)  {
        when 1:
                return new serviceImpl1();
        when 2:
                return new serviceImpl2();
        when 3:
                return new serviceImpl3();
    }
}

这两点都是@Component无法做到,只能@Bean实现,所以说@Bean更加灵活。

2)@Component通常是通过类路径扫描来自动装配到Spring容器中。而@Bean通常我们会在该注解的方法中定义产生这个bean的逻辑。

我们可以加一些@Conditional,@ConditionalOnBean等等一些注解来控制是否声明该Bean,不会一开始就自动装配到Spring容器中。

比如

public class MacCondition implements Condition {

   @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        Environment environment = conditionContext.getEnvironment();
        String property = environment.getProperty("os.name");
        if (property.contains("Mac")) {
            log.info("当前操作系统是:Mac OS X");
            return true;
        }
        return false;
    }
}

@Configuration
public class ConditionalConfig {
    /**
     * 如果MacCondition的实现方法返回true,则注入这个bean
     */
    @Bean("mac")
    @Conditional({MacCondition.class})
    public SystemBean systemMac() {
        log.info("ConditionalConfig方法注入 mac实体");
        return new SystemBean("Mac ios系统","001");
    }
}

上面的例子表示,如果当前操作系统是Mac,才会注入当前Bean。这个也只能 @Bean 注解才能实现。

总结:@Component和@Bean都是用来注册Bean并装配到Spring容器中,但是Bean比Component的自定义性更强。可以实现一些Component实现不了的自定义加载类。

二、springboot装配依赖包中的bean

当SpingBoot主类启动的时候,@SpringBootApplication注解会默认去扫描的自己所在包路径和它的子包路径下的所有需要装配的类,自动装配到spring的bean容器中。
但是如果你提供了一个Jar包供第三方用户使用,那么你这个jar包中的Bean,能被第三方加载么?
这就要看你当前项目的包名和你引用的第三方Jar包的包名是否一致了?如果一致,第三方依赖包中的bean可以直接加载,如果不一致,则无法加载第三方依赖中的bean。
例如,如果你当前项目本包的地址是com.jincou,而你引用的第三方Jar的本包也是 com.jincou,那么第三方Jar的Bean就可以被扫描到并注入到spring的容器中。如果你当前项目本包的地址是com.jincou ,而你引用的第三方Jar的本包是 com.third,那么也就是第三方Jar的Bean无法被扫描到,所以也就无法注入到Spring容器中。

比如这里有个第三方的Bean。要如何做才能被扫描注入到Spring容器中呢。

package com.third.bean;

import org.springframework.stereotype.Component;

/**
 * @Description: 这个bean作为第三方bean 给依赖该jar包的项目使用
 */
@Component
public class ThirdComponentBean {
    private String type = "第三方ThirdComponent注解生成bean实体";
}

1、ComponentScan注解

很简单,既然@SpringBootApplication注解默认扫描只是当前项目的本包和它的子包,那就想办法让它扫描第三方jar的包就好了。

/**
 * @Description: Springboot 启动类
 */
@ComponentScan(basePackages ={"com.third.bean"})
@SpringBootApplication()
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

@ComponentScan主要就是定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中。

需要装配的类也就是上面加了@Controller,@Service,@Repository,@Component,@Configuration等等的注解的Bean到IOC容器中。

这里不一定要加在启动类上,你可以加在加在装配的类上,但建议加在启动类上,比较直观,后期如果要改动或者去除也比较好找。

2、Import注解

@ComponentScan是扫描整个包,但其实你可能只需注入一个或者几个指定的Bean,那我们可以考虑用 @Import 注解

@Import(value= com.third.bean.ThirdComponentBean.class)
@SpringBootApplication()
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

这样做同样也会成功的将ThirdComponentBean对象注入到Spring的bean容器中。

3、spring.factories文件中配置bean

上面两种注入方式都有个很明显缺点,就是如果我需要引用外部jar包的Bean的时候,都需要在当前项目配置 @ComponentScan 或者 @Import 去扫描才能注入当前Bean,这样显然不够友好。

可不可以当前项目什么都不做就可以直接引用第三方jar的Bean呢?

当然可以。

我们只需要在将配置放在第三方jar指定的文件中即可,使用者会自动加载,从而避免的代码的侵入

在资源目录下新建目录 META-INF
在 META-INF 目录下新建文件 spring.factories
在文件中添加下面配置

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.third.bean.ConfigurationBean

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

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

相关文章

Linux环境下安装MySQL5.7.20(源码安装)

📣📣📣 哈喽!大家好,本专栏主要发表mysql实战的文章,文章主要包括: 各版本数据库的安装、备份和恢复,性能优化等内容的学习。。 📣 ***如果需要观看配套视频的小伙伴们,请…

单体架构改造为微服务架构之痛点解析

1.微服务职责划分之痛 1.1 痛点描述 微服务的难点在于无法对一些特定职责进行清晰划分,比如某个特定职责应该归属于服务A还是服务B? 1.2 为服务划分原则的痛点 1.2.1 根据存放主要数据的服务所在进行划分 比如一个能根据商品ID找出商品信息的接口,把…

Redis持久化(RDB、AOF)详解

Redis持久化详解 一、Redis为什么需要持久化? Redis 是一个基于内存的数据库,拥有极高的读写性能,但是内存中的数据在断电或服务器重启时会全部丢失,因此需要一种持久化机制来将数据保存到硬盘上,以便在需要时进行恢复…

R语言数据分析案例34-基于ARIMA模型的武汉市房价趋势与预测研究

一、背景阐述 房地产行业对于国民经济和社会及居民的发展和生活具有很大的影响,而房价能够体现经济运转的好坏,因而房价的波动牵动着开发商和购房者的关注,城市房价预测是一个研究的热点问题,研究房价对民生问题具有重要意义。 …

【面试干货】Java中的++操作符与线程安全性

【面试干货】Java中的操作符与线程安全性 1、什么是线程安全性?2、 操作符的工作原理3、 操作符与线程安全性4、如何确保线程安全?5、 结论 💖The Begin💖点点关注,收藏不迷路💖 在Java编程中,操…

思维导图MindManager2024最新版,让你的思维飞起来!

亲爱的朋友们,今天我要跟大家分享一款我近期深度使用并彻底被种草的神器——MindManager2024最新版本的思维导图软件。作为一位对效率和创意有着极高追求的内容创作者,我几乎尝试过市面上所有的思维导图工具,而MindManager2024无疑是其中的佼…

跟着DW学习大语言模型-什么是知识库,如何构建知识库

建立一个高效的知识库对于个人和组织来说非常重要。无论是为了个人学习和成长,还是为了组织的持续创新和发展,一个完善的知识管理系统都是不可或缺的。那么,如何建立一个高效的知识库呢? 在建立知识库之前,首先需要确定…

【办公类-51-01】月评估数字生成01-平均数空值

期末需要制作月评估,每月给孩子的能力水平打分。 以前我是做在EXCEL里,手动打分,然后用公式计算1、2、3出现的个数,然后计算平均数,最后复制到Word里。 因为是手动计算,每次都要算很长时间,确保…

借助TheGraph 查询ENS信息

关于ENS (以太坊域名服务) ENS 全称是 Ethereum Name Service,它是一个建立在以太坊区块链上的去中心化域名系统。 ENS 在 Web3 领域发挥着重要作用,主要有以下几个方面: 可读性更好的地址: ENS 允许用户将复杂的以太坊地址(如 0x12345…) 映射为更简单易记的域名。这极大地提…

KUBIKOS - Animated Cube Mini BIRDS(卡通立方体鸟类)

软件包中添加了对通用渲染管线 (URP) 的支持! KUBIKOS - 动画立方体迷你鸟是17种不同的可爱低多边形移动友好鸟的集合!每只都有自己的动画集。 完美收藏你的游戏! +17种不同的动物! + 低多边形(400~900个三角形) + 操纵和动画! + 4096x4096 纹理图集 + Mecanim 准备就绪…

生命在于学习——Python人工智能原理(4.3)

三、Python的数据类型 3.1 python的基本数据类型 3.1.4 布尔值(bool) 在Python中,布尔值是表示真或假的数据类型,有两个取值,True和False,布尔值常用于控制流程、条件判断和逻辑运算,本质上来…

项目实训-接口测试(十八)

项目实训-后端接口测试(十八) 文章目录 项目实训-后端接口测试(十八)1.概述2.测试对象3.测试一4.测试二 1.概述 本篇博客将记录我在后端接口测试中的工作。 2.测试对象 3.测试一 这段代码是一个单元测试方法,用于验证…

idea 开发工具properties文件中的中文不显示

用idea打开一个项目,配置文件propertise中的中文都不展示,如图: 可修改idea配置让中文显示: 勾选箭头指向的框即可,点击应用保存,重新打开配置文件,显示正常

篮球联盟管理系统

管理员账户功能包括:系统首页,个人中心,管理员管理,球员管理,用户管理,球队管理,论坛管理,篮球资讯管理,基础数据管理 前台账户功能包括:系统首页&#xff0…

Cell2Sentence:为LLM传输生物语言

像GPT这样的LLM在自然语言任务上表现出了令人印象深刻的性能。这里介绍一种新的方法,通过将基因表达数据表示为文本,让这些预训练的模型直接适应生物背景,特别是单细胞转录组学。具体来说,Cell2Sentence将每个细胞的基因表达谱转换…

前端架构(含演进历程、设计内容、AI辅助设计、架构演进历程)

前端架构的演进历程 前端架构师的必要条件 全面的技术底蕴全局观(近期 远期)业务要有非常深刻的理解沟通协调能力和团队意识深刻理解前端架构的原则和模式 前端架构的设计内容 技术选型(库、工具、标准规范、性能、安全、扩展性 )设计模式及代码组织(模…

ADS SIPro使用技巧之RapidScan-Z0

PCB走线的阻抗对每个网络的信号完整性至关重要,但是,验证每个信号是不切实际的,尤其对于设计复杂度很高的产品而言,设计者的有限精力只能用于关注关键的设计点,这一过程往往会造成一些设计的疏忽从而导致错误。 ADS SI…

97. 交错字符串(leetcode)

97. 交错字符串(leetcode) 题目描述 给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串: s s1 …

图书管理系统(详解版 附源码)

目录 项目分析 实现页面 功能描述 页面预览 准备工作 数据准备 创建数据库 用户表 创建项目 导入前端页面 测试前端页面 后端代码实现 项目公共模块 实体类 公共层 统一结果返回 统一异常处理 业务实现 持久层 用户登录 用户注册 密码加密验证 添加图书…

串口小工具(来源网络,源码修改)

从CSDN 中的一位博主的分享做了一些修改 QtSerial 的配和更稳定些 信号和槽 … … 更不容易崩 # This Python file uses the following encoding: utf-8 import sys import timefrom PySide6.QtGui import QIcon, QTextCursor from PySide6.QtWidgets import QApplication, QWi…