SpringBoot Bean被加载时进行控制
作者:零维展开智子 发布时间:2022-10-01 14:06:53
序章
简介: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。
来源:https://blog.csdn.net/weixin_53535434/article/details/128907086


猜你喜欢
- 为什么需要互斥量在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同
- ComparableComparable 是排序接口。若一个类实现了Comparable接口,就意味着“该类支持排序”。 即然实现Compa
- import java.io.BufferedReader; import java.io.IOException;  
- Object是所有类的父类,也就是说java中所有的类都是直接或者间接继承自Object类。比如你随便创建一个classA,虽然没有明说,但
- @RestControllerAdvice与@ControllerAdvice的区别@RestControllerAdvice注解与@Con
- 1、python的每一个语句的后面可以添加分号也可以不添加分号;在一行有多条语句的时候,必须使用分号加以区分2、查看Python版本号,在D
- 我们讲一下Criteria查询,这个对于不是太熟悉SQL语句的我们这些程序员来说是很容易上手的。 废话不多说,看一下例子:&nbs
- 本文实例为大家分享了android UI绘制加减号按钮的具体代码,供大家参考,具体内容如下在项目中我们常常会用到这么一个view。这时候我们
- ADO.NET数据访问技术的一个突出特点就是支持离线访问,而实现这种离线访问的技术核心急速DataSet对象,该对象通过数据驻留在内存来实现
- 继续我们的源码解析,上一篇文章我们介绍了Activity的启动流程,一个典型的场景就是Activity a 启动了一个Activity b,
- 使用版本:spring-boot: 2.1.6.RELEASEsping: 5.1.8.RELEASEjava: openjdk 11.0.
- Runtime.getRuntime().exec 路径包含空格1. 现象java代码通过Runtime.getRuntime().exec
- 本文实例为大家分享了Rxjava实现轮询定时器的具体代码,供大家参考,具体内容如下作用1、实现了延迟若干毫秒后,执行next操作,只执行一次
- 摘要:Java8通过Function获取字段名,解决硬编码,效果类似于mybatis-plus的LambdaQueryWrapper。本文总
- 简述最近做的公司项目,图片比较多,不想给其存储到自己服务器上,就买了阿里云的OSS服务器来哦进行存储,其实集成第三方平台,一般没什么难度,当
- 由于公司项目的需求,需要绘制一条竖直的间断线作为分割线。这个可坑了爹了,以前只搞过水平的间断线,只要通过shape也可以简单的画出来,但是千
- 在Java中,HashMap是一种常用的数据结构,它以键值对的形式存储和管理数据。然而,由于HashMap在多线程环境下存在线程安全问题,因
- 1.位置:如下:如果没有则在相同位置新建一个2. 添加端口号,修改:如图server.port=8080启动项目就会发现端口号已经成为你刚才
- 本文实例为大家分享了java实现在线聊天系统的具体代码,供大家参考,具体内容如下本博客是博主在观看相关视频后写下的代码,希望能够帮助大家掌握
- 一、分析这篇将会讲解撤销反撤销功能的实现,先讨论一下这个原理是怎么样实现的。每次撤回的内容,内容是怎么定义呢? 其实就是每一笔,每一笔作为撤