SpringBoot Bean被加载时进行控制

目录
  • 序章
  • 加载控制@Conditional派生注解
    • 这是我未加控制前的代码
    • 控制后
  • bean依赖的属性配置

序章

简介:bean的加载控制指根据特定情况对bean进行选择性加载以达到适用项目的目标。

根据之前对bean加载的八种方式,其中后面四种是可以对bean被加载时进行控制。

我拿第六种来举个例子。

之前也举过例子,但是实际开发呢,一般不会那么使用。

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        try {
            Class<?> name = Class.forName("yi.beans.kun");
            if (name!=null){
                return new String[]{"yi.beans.Cat"};
            }
        }catch (ClassNotFoundException e){
            return new  String[0];
        }
        return null;
    }
}

通过查看某个类是否存在来控制是否加载目标类。

这个类我是不存在的。

import org.springframework.context.annotation.Import;
import yi.beans.MyImportSelector;
@Import(MyImportSelector.class)
public class AConfig {
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import yi.config.AConfig;
public class App3 {
    public static void main(String[] args) {
        ApplicationContext context=new AnnotationConfigApplicationContext(AConfig.class);
        String[] names = context.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}

所以我是没有加载这个bean的,还是老话,前面的那些暂时不看。

加载控制@Conditional派生注解

到了这里,你的spring项目就该换成springboot项目了,pom.xml中添加坐标,我就不多说了,这就是springboot的注解,源代码中大量使用。

这是我未加控制前的代码

import org.springframework.context.annotation.ComponentScan;
@ComponentScan("yi.beans")
public class AConfig {
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import yi.config.AConfig;
public class App3 {
    public static void main(String[] args) {
        ApplicationContext context=new AnnotationConfigApplicationContext(AConfig.class);
        String[] names = context.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}

有猫,有狗,有老鼠,只不过我给他们都起了名字,你们很容易就会看出来。

现在我要对猫这个bean在创建时加一控制。

控制后

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;
import org.springframework.stereotype.Component;
@ConditionalOnClass(Mouse.class)    //要加载猫,必须要有老鼠这个bean
@ConditionalOnBean(name = "zhizhi")     //而且这个老鼠bean的名字必须是“zhizhi”
@ConditionalOnMissingClass("yi.beans.Dog")      //但是不能有狗,猫捉老鼠不想有狗
@ConditionalOnNotWebApplication     //环境必须为非Web环境
@Component("miao")  //猫的bean叫“miao”
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Cat {
    String shout;
}

这里我加了几个常见的派生注解,其他的代码都是不用变的,我的bean里卖虽然有一个叫做“zhizhi”的老鼠,但是有狗,所以猫是加载不出来的。

其中的

@ConditionalOnClass
@ConditionalOnBean

这两个注解非常相似,一般就用上面那个控制类的字节码或者路径。下面那个获取bean的名字,搭配使用就好了。

bean依赖的属性配置

先定义两个最基础的bean

import lombok.Data;
@Data
public class Mouse {
    private String name;
    private int age;
}
import lombok.Data;
@Data
public class Cat {
    private String name;
    private int age;
}

cartoon:
  cat:
    name: "图多盖洛"
    age:  5
  mouse:
    name: "泰菲"
    age: 1

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "cartoon")
public class CartoonProperties {
    private Cat cat;
    private Mouse mouse;
}
import lombok.Data;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Data
@Component
@EnableConfigurationProperties(CartoonProperties.class)
public class CartoonCatAndMouse {
    private Cat cat;
    private Mouse mouse;
    private CartoonProperties cartoonProperties;
    public CartoonCatAndMouse(CartoonProperties cartoonProperties){
        this.cartoonProperties=cartoonProperties;
        this.cat=new Cat();
        this.cat.setName(cartoonProperties.getCat()!=null&& StringUtils.hasText(cartoonProperties.getCat().getName())?
                cartoonProperties.getCat().getName():"Tom");
        this.cat.setAge(cartoonProperties.getCat()!=null&& cartoonProperties.getCat().getAge()!=0?
                cartoonProperties.getCat().getAge():6);
        this.mouse=new Mouse();
        this.mouse.setName(cartoonProperties.getMouse()!=null&&StringUtils.hasText(cartoonProperties.getMouse().getName())?
                cartoonProperties.getMouse().getName():"Jerry");
        this.mouse.setAge(cartoonProperties.getMouse()!=null && cartoonProperties.getMouse().getAge()!=0?
                cartoonProperties.getMouse().getAge():2);
    }
    public void play() {
        System.out.println(cat.getAge()+"岁的"+cat.getName()+"和"+mouse.getAge()+"岁的"+mouse.getName()+"打起来了");
    }
}
import com.yi.bean.CartoonCatAndMouse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootBean2ApplicationTests {
    @Autowired
    private CartoonCatAndMouse cartoonCatAndMouse;
    @Test
    void contextLoads() {
        cartoonCatAndMouse.play();
    }
}

可以看到加载的就是我们自己写的配置,现在我把配置注解一部分,我们再来看运行结果。

cartoon:
  cat:
#    name: "图多盖洛"
    age:  5
  mouse:
#    name: "泰菲"
    age: 1

可以看到,没有写的属性使用的就是默认属性,也就是自动配置的思想,只有在调用的时候才会生成bean,默认的bean也不会在项目加载时就添加,这样压力会很大。如果我们没有使用某个第三方的bean,我们的项目启动时也并不会加载默认的bean。

到此这篇关于SpringBoot Bean被加载时进行控制的文章就介绍到这了,更多相关SpringBoot Bean加载控制内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot Bean花式注解方法示例上篇

    目录 1.XML方式声明 2.注解法@Component 3.完全注解式 4.简化注解@Import 1.XML方式声明 这里我举两个例子,一个是自定义的bean,另一个是第三方bean,这样会全面一些. 你还可以定义这个bean的模式,有单例模式和多例模式,prototype代表多例,singleton代表单例. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://ww

  • SpringBoot自定义bean绑定实现

    目录 自定义bean绑定 导入第三方bean 第三方bea通过配置文件注参数 出现Prefix must be in canonical form @EnableConfigurationProperties()和@ConfigurationProperties的区别 解除@ConfigurationProperties注解警告 @ConfigurationProperties的松散绑定 自定义bean绑定 在配置文件中写入 servers: ipAddress: 192.158.0.1 por

  • SpringBoot Bean花式注解方法示例下篇

    目录 1.容器初始化完成后注入bean 2.导入源的编程式处理 3.bean裁定 拓展 4.最终裁定 1.容器初始化完成后注入bean import lombok.Data; import org.springframework.stereotype.Component; @Component("miao") @Data public class Cat { } 被注入的JavaBean import org.springframework.context.annotation.Con

  • SpringBoot bean查询加载顺序流程详解

    目录 背景 探索-源码 进一步思考 背景 SpringBoot bean 加载顺序如何查看,想看加载了哪些bean, 这些bean的加载顺序是什么? 实际加载顺序不受控制,但会有一些大的原则: 1.按照字母顺序加载(同一文件夹下按照字母数序:不同文件夹下,先按照文件夹命名的字母顺序加载)2.不同的bean声明方式不同的加载时机,顺序总结:@ComponentScan > @Import > @Bean   这里的ComponentScan指@ComponentScan及其子注解,Bean指的是

  • SpringBoot选择自有bean优先加载实现方法

    目录 背景介绍 实现方法 DependsOn注解 ApplicationContextInitializer 简单Demo 背景介绍 在一些需求中,可能存在某些场景,比如先加载自己的bean,然后自己的bean做一些DB操作,初始化配置问题,然后后面的bean基于这个配置文件,继续做其他的业务逻辑.因此有了本文的这个题目. 实现方法 DependsOn注解 这个@DependsOn网上实现方法很多,依赖的bean数目较少的话,比较好弄,但数目变多后,就比较麻烦了,每个类都需要重新写一遍,因此推荐

  • SpringBoot Bean被加载时进行控制

    目录 序章 加载控制@Conditional派生注解 这是我未加控制前的代码 控制后 bean依赖的属性配置 序章 简介:bean的加载控制指根据特定情况对bean进行选择性加载以达到适用项目的目标. 根据之前对bean加载的八种方式,其中后面四种是可以对bean被加载时进行控制. 我拿第六种来举个例子. 之前也举过例子,但是实际开发呢,一般不会那么使用. import org.springframework.context.annotation.ImportSelector; import o

  • 如何正确控制springboot中bean的加载顺序小结篇

    1.为什么需要控制加载顺序 springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题.在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功能. 在一般业务场景,可能你不大关心一个bean是如何被注册进spring容器的.只需要把需要注册进容器的bean声明为@Component即可,spring会自动扫描到这个Bean完成初始化并加载到spring上下文容器. 而当你在项目启动时需要提前做一个业务的初始化工作时,或者你正在开发某个中间

  • Spring中Bean的加载与SpringBoot的初始化流程详解

    目录 前言 第一章 Spring中Bean的一些简单概念 1.1 SpingIOC简介 1.2 BeanFactory 1.2.1 BeanDefinition 1.2.2 BeanDefinitionRegistry 1.2.3 BeanFactory结构图 1.3 ApplicationContext 第二章 SpringBoot的初始化流程 2.1 准备阶段 2.2 运行阶段 2.2.1 监听器分析 2.2.2 refreshContext 2.3 总结 前言 一直对它们之间的关系感到好奇

  • 在springboot中实现个别bean懒加载的操作

    懒加载---就是我们在spring容器启动的是先不把所有的bean都加载到spring的容器中去,而是在当需要用的时候,才把这个对象实例化到容器中. @Lazy 在需要懒加载的bean上加上@Lazy就可以了 补充知识:springboot组件懒加载的坑及加载规则 什么是懒加载? 懒加载的意思是不在项目启动的时候实例出来这个组件 @RestController public class ApiController { @Autowired Skill kobSkillImpl; @Request

  • SpringBoot的reload加载器的方法

    背景 springboot越来越多的被大家所使用SpringBoot DevTool实现热部署 出现了相同类castException 分析 首先确定出现相同类的castException比如是由于classloader不同造成的. 一个class是否相同取决于两个因素 classloader相同 class文件相同 即不同classloader解释出来的class是不同的class 我们在学习jdbc的时候常见的使用 /** * Returns the {@code Class} object

  • 浅谈SpringBoot资源初始化加载的几种方式

    目录 一.问题 二.资源初始化 一.问题 在平时的业务模块开发过程中,难免会需要做一些全局的任务.缓存.线程等等的初始化工作,那么如何解决这个问题呢?方法有多种,但具体又要怎么选择呢? 二.资源初始化 1.既然要做资源的初始化,那么就需要了解一下springboot启动过程(这里大体说下启动过程,详细:https://www.jb51.net/article/133648.htm) 按照前面的分析,Spring-boot容器启动流程总体可划分为2部分: 执行注解:扫描指定范围下的bean.载入自

  • SpringMVC bean实现加载控制方法详解

    目录 1.Spring配置类排除加载SpringMVC的bean 2.Servlet容器配置类简洁开发 1.Spring配置类排除加载SpringMVC的bean SpringMVC 通常只需要加载 controller 包内的 bean,而 Spring 需要加载 dao 和 service 包内的 bean,为了省事,Spring 配置类经常设置扫描的包为一个大范围的包(包含 dao 和 service 在内的包),此时 Spring 会错误或者多余地加载到 controller 包内的 b

  • 详解Spring简单容器中的Bean基本加载过程

    本篇将对定义在 XMl 文件中的 bean,从静态的的定义到变成可以使用的对象的过程,即 bean 的加载和获取的过程进行一个整体的了解,不去深究,点到为止,只求对 Spring IOC 的实现过程有一个整体的感知,具体实现细节留到后面用针对性的篇章进行讲解. 首先我们来引入一个 Spring 入门使用示例,假设我们现在定义了一个类 org.zhenchao.framework.MyBean ,我们希望利用 Spring 来管理类对象,这里我们利用 Spring 经典的 XMl 配置文件形式进行

  • 详解Spring中Bean的加载的方法

    之前写过bean的解析,这篇来讲讲bean的加载,加载要比bean的解析复杂些,从之前的例子开始. Spring中加载一个bean的方式: TestBean bean = factory.getBean("testBean"); 来看看getBean(String name)方法源码, @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, nul

随机推荐