0

I am implementing a third party library that uses Spring, which is declaring a Filter in the following way:

@Bean
@Autowired
public Filter filter() {
    return new Filter();
}

I load the configuration class to my application with a @Import(Configuration.class). My Spring Boot application loads the Filter and seems to try to use it, but I don't want that. How can I make Spring ignore such Beans, i.e., simply don't load them (supposing the third party library can work without them)?

Daniel Pop
  • 456
  • 1
  • 6
  • 23
  • Can you change that 3rd party library? I don't get why they have both `@Bean` and `@Autowired` on that method. – Wim Deblauwe Jun 16 '23 at 07:02
  • No, unfortunately I cannot. – Daniel Pop Jun 16 '23 at 07:04
  • Use any `@Conditional...` annotation. Example `@ConditionalOnProperty(prefix = "enable", value = {"myFilter"}, havingValue = "true", matchIfMissing = true`)` . And Bean won't create if you use this `enable.myFilter=false` in the property. – Numichi Jun 16 '23 at 07:07
  • @Numichi how can I annotate this Bean that is declared in a third party library? I can't access the code. – Daniel Pop Jun 16 '23 at 07:20
  • 2
    Maybe remove the Bean manually from the context afterwards like explained here (https://stackoverflow.com/questions/6855811/how-can-i-remove-a-singleton-spring-bean-from-applicationcontext) . Although this definitely isn't the cleanest solution and feels very hacky – berse2212 Jun 16 '23 at 07:22
  • @berse2212 this could be a solution indeed (or simply create a Bean with a similar signature) together with a `@Primary` annotation, that would force Spring to choose it instead of the third party, but I was looking for a cleaner a solution. For starters, I couldn't understand why they would bring together `@Bean` and `@Autowired`. – Daniel Pop Jun 16 '23 at 07:29
  • Is this part of an `@Configuration` class you import or is it part of some auto configuration? Please provide some more information. – M. Deinum Jun 16 '23 at 10:24
  • This is part of a Configuration I import with `@Import(Configuration.class)` – Daniel Pop Jun 16 '23 at 10:39
  • 1
    one approach: copy (don't/before import) all configuration except "unwanted" parts, another: override the bean (with a "no-op-filter" e.g.) – xerx593 Jun 16 '23 at 10:47
  • 1
    @xerx593 I managed to reach out to the creator of the external library and he suggested a solution akin to your first one. Can you add it as an answer so that I can mark it as accepted? – Daniel Pop Jun 19 '23 at 09:46

2 Answers2

1

Spring Boot includes the @Profile annotation.

Make the "to be ignored" classes with a specific @Profile and Spring Boot will ignore them when the identified profile is not active.

For example:

@Profile("BlammyProfile")
public class Blammy
{
  ...
}

Here is a Spring Profile Baeldung Article link

DwB
  • 37,124
  • 11
  • 56
  • 82
1

We followed provider recommendation/decided for:

Appropriate and edit config

Means: Copy, paste and edit the original "Configuration" instead of/before importing/scanning it:

@Configuration
class MyConfig { 
  // copy, paste & edit original (com.third.party) Configuration (omit unwanted parts/beans)
} // <- use this

One alternative approach is:

Destroy Bean

As described by:

How can i remove a singleton spring bean from ApplicationContext?

..., we only need to "plug it" (e.g.) simple like:

@Bean
BeanFactoryAware myDestroy() {
  return (beanFactory) -> {
    ((BeanDefinitionRegistry) beanFactory).removeBeanDefinition("filter"); // bean name (+ type, see [javadoc](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/support/BeanDefinitionRegistry.html))
  };
}

..also possible:

Replace Bean

Here we replace the Bean (by type and name), with an "NO-OP" bean:

@Primary @Bean
public Filter filter() { // same name & type!
    return new com.my.example.DoesNothingFilter(); // as name (and interface) implies
}

...

Ideally

Provider would make it @ConditionalOnXXX/bind it to @Profile! :)

... (+any other alternatives)

xerx593
  • 12,237
  • 5
  • 33
  • 64