首页 > 其他分享 >SpringBoot--Bean对象管理(Bean对象扫描、Bean对象注册、注册条件)

SpringBoot--Bean对象管理(Bean对象扫描、Bean对象注册、注册条件)

时间:2024-11-13 11:43:27浏览次数:3  
标签:对象 Country bean public Bean 注册 注解 class

目录

(一)Bean扫描 

1.通常用来扫描包的方法

2.在SpringBoot中如何扫描 

(二)Bean对象的注册

案例测试: 

准备工作:

 1.安装一个jar包:​编辑

​编辑 2.将刚才安装好的坐标引入进来:

 @Bean

1.在启动类中添加(不推荐)

 2.定义一个配置类

 @Import

1.导入配置类

2.导入ImportSelector接口实现类

 3.使用@EnableXxx注解,来封装@Import注解

 (三)注册条件

@ConditionalOnProperty

 @ConditionalOnMissingBean

@ConditionOnClass 


(一)Bean扫描 

1.通常用来扫描包的方法

使用标签:在 xml文件中可以借助<context:component-scan base-package="com.it"/>标签来指定要扫描的包路径

使用配置类的方式:@ComponentScan(basePackages="com.ti")使用注解来指定要扫描的包路径

2.在SpringBoot中如何扫描 

 为什么在使用SpringBoot的时候,既不需要使用compo-scan标签,也不用写@ComponentScan注解,就能扫描到我们写的包?

SpringBoot工程需要一个启动类,在启动类上需要添加一个注解@SpringBootApplication,

并且在启动这个SpringBootApplication的时候,把当前启动类的字节码文件作为参数传递进去了。

核心原因就是@SpringBootApplication这个注解,这个注解本质上是一个组合注解,它整合了ComponentScan注解,这也是为什么我们不需要手动添加这个注解,也能自动扫描到那些包,在使用ComponentScan注解的时候,不指定包路径,那么它默认扫描的是添加了该注解的类所在的包及其子包

SpringBoot工程默认扫描所在的包,及其子包

举例:

若将Controller这个包移到与启动类不同的包,那么再次输入网址,则无法访问到用户的信息,因为SpringBoot工程扫描不到了

 若想扫描到启动类之外的包,那么就需要手动添加注解,以及包的路径

@ComponentScan(basePackages = "包路径")

(二)Bean对象的注册

注解说明位置
@Component声明bean的基础注解不属于一下三类是,有此注解
@Controller@Component的衍生注解标注在控制类上
@Service@Component的衍生注解标注在业务类上
@Reposity@Component的衍生注解标注在数据访问类上(用于与mybatis整合,用得少)

如果要注册的bean对象来自于第三方(不是自定义的),是无法使用@Component及其衍生注解声明bean的(在jar包中的文件都是只读的,不可更改)

解决方法:

 Spring提供了两个注解来解决这个问题:

  1. @Bean
  2. @Import

案例测试: 

准备工作:

 1.安装一个jar包:

命令:

mvn install:install-file -Dfile=D:\BaiduNetdiskDownload\02_Bean注册资料\02_Bean注册资料\common-pojo-1.0-SNAPSHOT.jar -DgroupId=cn.itcast -DartifactId=common-pojo -Dversion=1.0 -Dpackaging=jar 

标颜色的那段需要更改

执行命令之前必须要确认Maven的环境变量是好的

这样即安装成功:

D:\Maven\maven-repository\cn\itcast\common-pojo\1.0 

 2.将刚才安装好的坐标引入进来:

<dependency>
  <groupId>cn.itcast</groupId>
  <artifactId>common-pojo</artifactId>
  <version>1.0</version>
</dependency>

 目标,将这两个类的bean注入到IOC容器中:

 @Bean

1.在启动类中添加(不推荐)

如果要注册第三方bean,建议在配置类中集中注册

@SpringBootApplication
public class SpringBootCreateManualApplication
{
    public static void main( String[] args )
    {
        ApplicationContext context=SpringApplication.run(SpringBootCreateManualApplication.class,args);

        Country country = context.getBean(Country.class);
        //若能正常输出,表示bean对象注入成功
        System.out.println(country);
    }

    //注入Country对象
    @Bean//将方法返回值交给IOC容器管理,成为IOC容器的bean对象
    public Country country(){
        return new Country();
    }
}

 2.定义一个配置类

@Configuration
public class CommonConfig {
    //注入Country对象
    @Bean//将方法返回值交给IOC容器管理,成为IOC容器的bean对象
    public Country country(){
        return new Country();
    }
}

正常获取到了: 

 获取Province:

//对象默认的名字是方法名
@Bean
public Province province(){
    return new Province();
}

System.out.println(context.getBean("province"));  根据名字获取

正常获取到: 

 @Import

  1. 导入配置类
  2. 导入ImportSelector实现类
1.导入配置类

即使配置类与启动类不在一个包下面,也能扫描到

@SpringBootApplication
@Import(CommonConfig.class)
public class SpringBootCreateManualApplication
{
    public static void main( String[] args )
    {
        ApplicationContext context=SpringApplication.run(SpringBootCreateManualApplication.class,args);

        Country country = context.getBean(Country.class);
        //若能正常输出,表示bean对象注入成功
        System.out.println(country);

        System.out.println(context.getBean("province"));
    }

}

如果配置类有多,可以通过数组的方式来输入 

 也可以使用ImportSelector接口实现类来让代码更加美观

2.导入ImportSelector接口实现类
  1. 首先定义一个类去实现这个接口
  2. 然后重写selectImports方法

@SpringBootApplication
//@Import(CommonConfig.class)
@Import(CommonImportSelector.class)
public class SpringBootCreateManualApplication
{
    public static void main( String[] args )
    {
        ApplicationContext context=SpringApplication.run(SpringBootCreateManualApplication.class,args);

        Country country = context.getBean(Country.class);
        //若能正常输出,表示bean对象注入成功
        System.out.println(country);

        System.out.println(context.getBean("province"));
    }

}

public class CommonImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"org.example.config.CommonConfig"};  //要注入到bean对象里面的全类名(可写多个)
    }
}

正常获取到,没问题: 

 优化:

创建一个文件来存放全类名,即需要扫描的文件,若将来有多个bean对象要注入,那么换行每一行写一个类名就行

public class CommonImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        //读取配置文件的内容
        List<String> imports=new ArrayList<>();
        InputStream is=CommonImportSelector.class.getClassLoader().getResourceAsStream("common.imports");
        BufferedReader br=new BufferedReader(new InputStreamReader(is));
        String line=null;
        try {
            while((line = br.readLine())!=null){
                imports.add(line);
            }
            br.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return imports.toArray(new String[0]);
    }

继续运行启动类:

正常获取到,没问题!!

 3.使用@EnableXxx注解,来封装@Import注解

创建@EnableCommonConfig组合注解

import org.example.config.CommonImportSelector;
import org.springframework.context.annotation.Import;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(CommonImportSelector.class)
public @interface EnableCommonConfig {
}

在启动类上使用@EnableXxx注解即可

获取成功:

 (三)注册条件

SpringBoot提供了设置注册生效条件的注解@Conditional

注解说明
@ConditionalOnProperty配置文件中存在对应的属性,才声明该bean
@ConditionalOnMissingBean当不存在当前类型的bean时,才声明该bean
@ConditionOnClass当前环境存在指定的这个类时,才声明该bean

@ConditionalOnProperty

将配置文件中的内容注释掉

@ConditionalOnProperty注解,如果配置文件中配置了指定的信息,则注入,否则不注入

@ConditionalOnProperty(prefix = "country",name = {"name","system"})

配置文件中没有内容,报错:

取消注释,正常注入:

 @ConditionalOnMissingBean

将配置文件中的内容注释掉

如果IOC容器中不存在Country对象,则注入Province对象,否则不注入

@ConditionalOnMissingBean(Country.class)

不存在Country对象,只注入Province

@ConditionOnClass 

如果当前环境中存在DispatcherServlet类,则注入Province对象,否则不注入

如果当前环境引入了web起步依赖,则环境中存在DispatcherServlet类,否则没有

由于这个项目没有引入web依赖,所以运行时报错了:

标签:对象,Country,bean,public,Bean,注册,注解,class
From: https://blog.csdn.net/2301_76890677/article/details/143719291

相关文章

  • 避免将 let 与数组和对象一起使用
    首先,让我们明确一点……使用let数组和对象本身根本不成问题。但有一些特定的注意事项可能会导致在某些情况下避免使用它:重新分配与变异众所周知,let允许我们重新分配变量本身,这可能会导致混乱或数据丢失。对象/数组可能会意外地被重新分配一整套新数据(新对象/新数组)。使用const......
  • 基于Angular的动画展示网站+登录注册(cognito)
    项目介绍本项目为本人angular练习练手项目,是基于Angular的Web应用,用于展示和搜索Bangumi上的动画,使用API来自BangumiAPI。本项目使用GitHubActions自动部署到GitHubPages。项目名称my-angular-project-test地址:https://dreaife.github.io/my-angular-project-......
  • 汇编角度看值传递类对象
    首先奉上源代码classA{private:inti;public:A(){std::cout<<"defaultconstructoriscalled"<<std::endl;i=0;}A(int_i):i(_i){}A(constA&obj){std::cout<<"c......
  • JSON 处理技术:字符串与对象的转换
    JSON处理技术:字符串与对象的转换在现代Web开发中,JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,它基于JavaScript的一个子集。JSON格式易于人阅读和编写,同时也易于机器解析和生成。本文将探讨JSON.parse()和JSON.stringify()方法,这两个方法在处理JS......
  • 电脑录音软件 GiliSoft Audio Recorder Pro v13.2.0 注册码
    GilisoftAudioRecorderPro是一款专为Windows电脑设计的音频录制软件,它能够从电脑声音、麦克风、在线音乐等多种音频源捕捉声音。这款软件以其卓越的录音品质和多样化的功能,如定时录制和声音增强技术,帮助用户轻松提升录音质量。该版本已内置注册码,可以使用全部功能。软件截......
  • 图片批量处理工具 Light Image Resizer v7.0.9 注册码
    想要轻松压缩图片,提升工作效率?LightImageResizer中文便携正式版是您的理想选择。这款图片无损压缩工具让您能够快速调整图片大小,批量转换图像格式,一站式处理图片需求。该版本已内置注册码,可以使用全部功能。软件截图:使用说明:1、将压缩文件解压到固定位置,不要随意移动。......
  • 商标注册、遭遇撤三、复审如何提高成功率?
    提高商标注册成功率和商标遭遇撤三后复审成功率的策略如下:提高商标注册成功率:查询商标是否存在近似:在提交商标申请前,进行严格的商标查询,以减少与现有商标冲突的风险。原创商标:确保商标名称具有独特性,不模仿他人商标,以提高注册成功率。商标显著性:商标的显著性越强,越容易被识别......
  • 为什么要使用克隆?如何实现对象克隆?深拷贝和浅拷贝区别是什么
    有时需要复制一个对象,并且希望保留原有的对象进行接下来的操作。这时就需要使用克隆。如何实现对象克隆?实现Cloneable接口并重写clone方法:实现​​Cloneable​​接口后,可以调用​​Object.clone()​​方法来创建一个新的对象。通过序列化和反序列化实现深克隆:将对象转......
  • 【JAVA】Java基础—面向对象编程:构造方法-实现一个Car类,包含多个构造方法,创建不同的汽
    在Java中,构造方法则是用于创建对象的特殊方法。通过构造方法,可以在创建对象时初始化其属性。构造方法的重载允许我们根据不同的需求定义多个构造方法,从而灵活地创建对象。我们可以将汽车的构造方法比作汽车的配置选项。比如,当你购买一辆汽车时,你可以选择不同的配置,如颜色、型......
  • PLSQL 最新版永久免费注册(详解)
    打开plsql,登录或者不登录账号都可,进入菜单【帮助】->【注册】弹出框中依次录入以下信息:产品编号:ke4tv8t5jtxz493kl8s2nn3t6xgngcmgf3序列号:264452密码:xs374ca点击【注册】,即注册成功!......