添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • springboot 2.0.0.RELEASE
  • maven 3.5.0
  • 这里介绍内容为,在spring boot启动时,排除/不加载某些Bean。spring boot启动时,排除/不加载某些模块/AutoConfiguration类,看 这里

排除/不加载某些Bean

排除/不加载某些Bean时,需要使用@ComponentScan。具体做法,可以采用下面的方式:

  • 方式1:自定义 @ComponentScan
  • 方式2:自定义 @ComponentScans
  • 方式3:自定义 TypeExcludeFilter

方式1:自定义 @ComponentScan

假设:我在使用 RuoYi 的时候,想自己的实现 ShiroConfig,而不用 RuoYi 自带的 ShiroConfig ,且,不删除 RuoYi 自带的 ShiroConfig 类。

此种情况下,就需要启动项目时,不加载 ShiroConfig 类。

针对此种情况,可以这样做:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@ComponentScan(excludeFilters = {
			@Filter(type = FilterType.REGEX, pattern = {
				"com.ruoyi.framework.config.ShiroConfig"})
public class RuoYiApplication {
	...
  • 使用自定义的 @ComponentScan 注解替换 @SpringBootApplication 的注解。
  • 定义 excludeFilters 属性。该属性指定排除的Bean/类。
  • 使用正则表达式方式( FilterType.REGEX )排除类 "com.ruoyi.framework.config.ShiroConfig"

方式2:自定义 @ComponentScans

@SpringBootApplication 有些特殊,官方的解释是:same as @Configuration @EnableAutoConfiguration @ComponentScan

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
	...

你看!@SpringBootApplication 带了一个 @ComponentScan。一个 @ComponentScan 会影响 @ComponentScans(为啥?暂不清楚)。

所以,自定义 @ComponentScans 是应该这样:

@Configuration
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
@ComponentScans({
	@ComponentScan(
			basePackages = {"com.ruoyi"}, 
			excludeFilters = {
					@Filter(type = FilterType.REGEX, pattern = {
							"com.ruoyi.framework.config.ShiroConfig"})}),
	@ComponentScan(basePackages = {"com.third.package"}),
public class RuoYiApplication {
	...
  • 使用@Configuration @EnableAutoConfiguration @ComponentScans 替换了 @SpringBootApplication
  • 使用 @ComponentScans 是为了添加多个 @ComponentScan。只有一个 @ComponentScan 时,可以不用 @ComponentScans

方式3:自定义 TypeExcludeFilter

@SpringBootApplication 有些特殊,它带了一个 @ComponentScan

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
	...

你看!@SpringBootApplication 自带的 @ComponentScan 中已经有了自定义的 excludeFilters。可以利用此特性实现排除/不加载某些Bean。

  1. 实现自己的 TypeExcludeFilter
public class MyTypeExcludeFilter extends TypeExcludeFilter {
	@Override
	public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {
		if("com.ruoyi.framework.config.ShiroConfig".equals(metadataReader.getClassMetadata().getClassName())){
			System.out.println("skip >>>>>>> " + metadataReader.getClassMetadata().getClassName());
			return true;
		return false;
  1. MyTypeExcludeFilterApplicationContext Initializer 时注册Bean(通过注解注册的Bean,进入 Spring 容器太晚了,不起作用)。
public class MyTypeExcludeFilterApplicationContextInitializer 
			implements ApplicationContextInitializer<ConfigurableApplicationContext> {
	@Override
	public void initialize(ConfigurableApplicationContext applicationContext) {
		applicationContext.addBeanFactoryPostProcessor(new MyTypeExcludeFilterPostProcessor());
	private static class MyTypeExcludeFilterPostProcessor
			implements PriorityOrdered, BeanDefinitionRegistryPostProcessor {
		public static final String BEAN_NAME = "com.ruoyi." + "myTypeExcludeFilter";
		@Override
		public int getOrder() {
			return Ordered.HIGHEST_PRECEDENCE;
		@Override
		public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		@Override
		public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
			RootBeanDefinition definition = new RootBeanDefinition(
					MyTypeExcludeFilter.class);
			registry.registerBeanDefinition(BEAN_NAME, definition);
  1. 注册 MyTypeExcludeFilterApplicationContextInitializer
    src/main/resources 目录下创建文件META-INF/spring.factories(如果该文件已存在,则无须创建)。在文件META-INF/spring.factories中添加内容:
org.springframework.context.ApplicationContextInitializer=\
com.ruoyi.MyTypeExcludeFilterApplicationContextInitializer

说明:操作复杂,实测效果不理想,不推荐使用。

https://www.cnblogs.com/yql1986/p/9418419.html
https://stackoverflow.com/questions/41287276/when-should-i-use-typeexcludefilters-in-spring
https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/reference/htmlsingle/#boot-features-testing-spring-boot-applications-excluding-config

由于公司把redis相关的配置类,工具类放在了一个类似common的工程里,这样以后肯定不可避免的出现某些项目可能并不需要使用redis,但是还是依赖common里的别的一些类库 所以排除springboot启动加载的一些bean还是有意义的 首先由自己配置的RedisConfiuration类,还有RedisUtil类,可以使用@ComponentScan注解用来扫描加排除,不加Compon...
在项目中要移除这些不想自动注册的bean, 使用BeanDefinitionRegistryPostProcessor,直接在 解析完bean的注册信息后,直接移除就行,这样就不会创建bean。 @Component public class RemoveRegistyBeanFactoryPostProcessor imp
要使用 U-Boot,首先要确定 U-Boot 是否支持我们的使用芯片(开发板)。这就需要查看 ./config 目录下有没有对应的配置文件,或者说有没有类似的配置文件。如果直接有(对于一些通用的平台,U-Boot 已经添加好了一些默认配置),那么恭喜可以省事很多;如果没有(如果是自己画的板子,指定是没有),后续就牵扯到自己移植修改代码。具体步骤如下: 新增 MCU 的设备树文件:arch\
最近我们项目要和别的项目集成,本来自己项目的一套流程就不能用了,需要用其他项目的菜单用户等,这就需要调用他们的接口,但是调用他们的接口需要使用他们提供的restTemplate,因为他们加了自定义的headerInterceptor,会有各种认证。但是我们项目一个配置类中也定义了一个全局restTemplate @Primary @Bean public RestTemplate loadBalanced() { RestTemplate template = new RestTemplate();
阿里云的Schedulerx启动时需要阿里的tomcat,需要注册到阿里服务器上,不能使用懒加载方式,但测试时注入不成功,所以测试需要排除Schedulerx的Bean 1、Schedulerx的Bean单独放一个Config文件(测试不想初始化的Bean单独放一个文件) 一、SpringBoot测试去除某个配置文件不加载。 package com.suyun.svop.admin; import com.suyun.svop.SvopAdminApplication; import .
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; public class TelegramBot { public static void main(String[] args) throws IOException { String botToken = "YOUR_BOT_TOKEN_HERE"; String chatId = "YOUR_CHAT_ID_HERE"; String message = "Hello, world!"; String urlString = "https://api.telegram.org/bot" + botToken + "/sendMessage?chat_id=" + chatId + "&text=" + URLEncoder.encode(message, "UTF-8"); URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuilder result = new StringBuilder(); String line; while ((line = rd.readLine()) != null) { result.append(line); rd.close(); System.out.println(result.toString()); 在这个示例中,您需要将YOUR_BOT_TOKEN_HERE和YOUR_CHAT_ID_HERE替换为您的Telegram Bot的令牌和聊天ID。您可以在BotFather中获取令牌,而聊天ID可以通过与Telegram Bot对话并发送“/start”命令来获取。 这个示例使用GET请求发送消息,因此在发送消息之前,您需要确保您的电脑可以访问Telegram服务器。如果您的网络环境无法访问Telegram服务器,则需要使用代理或VPN。 【若依(ruoyi)】template might not exist or might not be accessible by any of the configured Template Res 45106