I want to exclude a single Spring bean that's included in the packages scanned by Spring's component scan. I'd like to do this by using some kind of exclude parameter of the #SpringBootApplication annotation. All of Spring Boot's documentation seems to explain how to exclude "auto configuration classes" like LiquibaseAutoConfiguration.class. I don't want to exclude an auto configuration class - I'd just like to exclude a single bean. I'm using Spring Boot 2.7.4. Does anyone know how to do this?
Related
Excluding several AutoConfiguration classes in Spring Boot is easy. Just exclude it from the application:
#SpringBootApplication(exclude = {
org.springframework.cloud.autoconfigure.RefreshAutoConfiguration.class,
org.springframework.cloud.openfeign.FeignAutoConfiguration.class,
})
But how can all AutoConfiguration from the package org.springframework.cloud can be excluded without adding all Spring Clouds AutoConfiguration classes to the exclude? That would be dozens if not hundred entries. And it would not be future proof as with every new Spring Cloud version new AutoConfiguration classes come along.
Using #ComponentScan would only work if #SpringBootApplication respective #EnableAutoConfiguration is not used. But that would remove all the convenient auto configuration capabilities, too.
Is there a way to achieve that programmatically? And how?
Removing Spring Clouds dependencies from the application is unfortunately not a feasible solution.
Why you want to exclude all classes from auto configuration ?
Most of the beans in Autoconfigurations are #conditional , they will not be created if you are providing your own.
Anyway you can look into AutoConfigurationImportSelector . As of now Spring boot allow only class and name for #EnableAutoConfigurtion exclude . if you want to write customize "AutoConfigurationImportSelector" , you can subclass and filter exclude by package after writing your own extended interface for EnableAutoConfiguration to write package method.
As I mentioned this will be the last thing I would like to do . just check #conditional dependency for auto configuration and provide your own beans is better solution.
In my project, I don't want to use #EnableAutoConfiguration. My Application.java has #ComponentScan, #Configuration and #Import annotation.
I have added spring boot actuator dependency in my pom.xml. But, when I try to access http://<>/acutuator/health, I get 404. I believe I need to specify some config class as part of Import annotation. I would need help in figuring out what that config would be.
#EnableAutoConfiguration makes Spring guess configuration based on the classpath, and that's what spring boot all about. If you find that specific auto-configuration classes that you do not want are being applied, you can use the exclude attribute of #EnableAutoConfiguration to disable them. For example:
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
Spring Boot's support for Spring data configuration is generally by org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport, and this class use the follow code to determine what packages to scan for repositories:
AutoConfigurationPackages.get(this.beanFactory)
So, basically Spring Data with Spring Boot only scan the package which contains the #EnableAutoConfiguration or #ImportAutoConfiguration, but not consider the #ComponentScan, Is this correct ?
The #ComponentScan annotation is a core Spring Framework feature to search for classes annotated with #Component. Since Spring Data repositories are interfaces (and not annotated), the #ComponentScan annotation won't pick them up.
If you are using Spring Data outside of Spring Boot, you can scan for Spring Data repositories using #EnableJpaRepositories with the basePackages attribute set.
When it comes to Spring Boot, there's usually no need to use either #ComponentScan or #EnableJpaRepositories. If you structure your code as suggested, both components and repositories will be picked up.
To get back to your original question about AbstractRepositoryConfigurationSourceSupport. If you look at the source of #SpringBootApplication you'll see it's annotated with #ComponentScan (to find #Components) and #AutoConfigurationPackage (via #EnableAutoConfiguration). The #AutoConfigurationPackage sets up AutoConfigurationPackages with the value that's later retrieved.
If you want to override the packages the Spring Data searches for repositories (for example in tests) you'll need to use #EnableJpaRepositories to completely override auto-configuration. I usually don't do this, but instead use #DataJpaTest and pick up my main configuration.
I have written some code in order test integration with mongoDB. Please find the link to the main method for running this spring boot application below,
https://github.com/siva54/simpleusercontrol/blob/master/src/main/java/com/siva/UserManagementApplication.java
From what I have read, An application should contain any of the configurations from the following URL to declare how the applications manages the context,
http://docs.spring.io/autorepo/docs/spring-boot/current/reference/html/using-boot-using-springbootapplication-annotation.html
I haven't used any of those contexts, However my application works fine and I'm able to run it without any issues. Am I missing something here? Can you please help with the info of how my application is able to start and manage the context/dependencies automatically?
Thanks in advance
#SpringBootApplication is equivalent of #Configuration, #EnableAutoConfiguration and #ComponentScan. Let's consider why your application works without of any of this three annotations.
Why it works without #Configuration:
When Spring will scan packages, it will find all classes marked by #Configuration and will use them as part of configuration. But in next line you manually passed UserManagementApplication as configuration source:
SpringApplication.run(UserManagementApplication.class, args);
So spring doesn't need to find this class by scan. Therefor it is not necessary to mark it by #Configuration.
Why it works without #ComponentScan:
Class UserManagementApplication has #ImportResource("classpath:spring/application-context.xml") annotation. That means file spring/application-context.xml will be included into configuration. And this file contains next line:
<context:component-scan base-package="com.siva.*" />
So, you don't need use annotation for scan packages, because you already declared it in the xml file.
Why it works without #EnableAutoConfiguration:
This annotation allows to Spring to try guess and configure the components automatically. For example, if you include the following dependency in your build.gradle:
dependencies {
compile 'org.springframework.boot:spring-boot-starter-data-mongodb'
}
Spring configures all the components required to work with MongoDB automatically. And all you need just specify host and user/pass in the aplication.proprties file.
But you preferred to declare all needed beans manually in the spring/application-context.xml file. So, you simply don't need #EnableAutoConfiguration annotation at all.
In Spring Boot, is there a way to prevent Auto Configuration of all modules? Basically am looking for something like #DisableAutoConfiguration instead of excluding specific configurations with class names.
Auto-configuration is enabled by the #EnableAutoConfiguration annotation. If you don't want to use auto-configuration, then omit this annotation. Note that #SpringBootApplication is itself annotated with #EnableAutoConfiguration so you'll have to avoid using it too. Typically, this would leave your main application class annotated with #ComponentScan and #Configuration.