I'm new to Spring Boot so sorry if this is too basic. My code takes a lot of time to build. I figured out that it's because Spring is loading a lot of config files that are not really needed.
My main file :
#EnableSwagger2
#SpringBootApplication
#IntegrationComponentScan
#EnableIntegration
public class MySystem {
public static void main(String[] args) {
run(MySystem.class, args);
}
}
I tried using #EnableAutoConfiguration(exclude = {classes to exclude}) but the unused classes imported by Spring boot on build time are too much to include here individually, there are hundreds of them. Is there a way to exclude unused config files in batch or in group? Or maybe I'm doing something wrong?
Related
I have create a spring-boot-2 gradle project, also in build.gradle file i have added Kafka related dependency which given below.
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-zipkin'
compile 'org.springframework.cloud:spring-cloud-starter-bus-kafka'
}
now i want to disable all Kafka related Auto configuration from application.yaml
file for that i have tried given below code in my yaml file.
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration
After implementing above things still the Kafka got Auto-configured and start integration of Kafka with the application.
Also i have tried below code but this is also not working for me.
#SpringBootApplication
#EnableAutoConfiguration(exclude = KafkaAutoConfiguration.class)
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
Now please can any one help me out, how can i disable all auto configuration related to kafka from yaml/properties file ?
Thanks,
Instead of #EnableAutoConfiguration(exclude = KafkaAutoConfiguration.class)
You should do #SpringBootApplication(exclude = KafkaAutoConfiguration.class)
I am learning spring boot. This is my spring boot project structure. I do intentionally keep my application.java in a different package to learn about #ComponentScan
Project source - https://github.com/kitkars/spring-boot
project structure
Error :
The application failed to start due to below error.
***************************
APPLICATION FAILED TO START
***************************
Description:
Field productRepository in com.test.service.ProductService required a bean of type 'com.test.repository.ProductRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.test.repository.ProductRepository' in your configuration.
Process finished with exit code 1
This is my Application.java
#SpringBootApplication
#ComponentScan(basePackages = "com.test")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Now If I move my Application.java under com.test, everything works just great.
What If my Application.java is not under com.test - can it not use the ComponentScan packages and start from there? All the controller, services, repositories etc are present under com.test.
The class annotated with #SpringBootApplication should be in your root package (by default all classes in this package and subpackages are scanned) or you need to specify other packages (controller, entity and others) in #ComponentScan.
Official documentation states:
We generally recommend that you locate your main application class in a root package above other classes.
Spring Boot relies heavily on default configuration. Consider this excerpt from #EnableAutoConfiguration annotation.
The package of the class that is annotated with
#EnableAutoConfiguration, usually via #SpringBootApplication, has
specific significance and is often used as a 'default'. For example,
it will be used when scanning for #Entity classes. It is generally
recommended that you place #EnableAutoConfiguration (if you're not
using #SpringBootApplication) in a root package so that all
sub-packages and classes can be searched.
The same logic implies to #ComponentScan, #EnableJpaRepositories and the above mentioned #EntityScan annotations. So, if you want to take control of component scanning, you should specify base packages explicitly for all of those annotations.
#SpringBootApplication(scanBasePackages = "com.test")
#EnableJpaRepositories(basePackages = "com.test")
#EntityScan(basePackages = "com.test")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Also note that in your case there is no need to use another #ComponentScan as you can provide arguments to Spring Boot's #ComponentScan via scanBasePackages attribute.
Please check the dependency 'org.springframework:spring-context-indexer if you have one, of course. In my case, this library has caused problems with submodules.
The problem was that only beans of the current gradle project were included in the index.
resolving do this in my application class.
#Configuration
#SpringBootApplication
#ComponentScan(basePackages = "{lamc.bar.*}")
For me, removing the #ComponentScan did the job.
SpringBoot should pick up all your components automatically, so long as your application structure is like this:
|-->package1
|-->package2
|Main.java
You should remove #Repository in com/test/repository/ProductRepository.java.
While modularising our project into different independent maven projects using spring boot and maven, we have came across a issue where autowiring of beans in multi module maven project is not working.
Just to give you an overview of the issue, below are the independent maven projects developed so far
Coreservices – Contains spring boot domain objects of whole application : Output JAR
DBservices1-Contains spring boot repositories and services(Database Services) to access database : Output JAR
Rewards -Contains Rewards module related files(Controllers, services(Business Logic Services), Views) : Output JAR
RewardsApp- Independent deployable maven project : Output WAR
Below is the dependency structure
RewardsApp-> Rewards -> DBservices1 -> Coreservices
The problem is #Autowired annotation used in Rewards and DBservices1 to fetch the mapped services annotated with #Service/#Repository are not available in RewardsApp Project.
As a workaround we have configured the beans in RewardsApp with #Bean annotation, then the services are available to the server to start successfully.
With this approach we need to manually configure all the beans in RewardsApp used in dependent projects.
We have many services and repositories in our application and we think creating beans like this not a proper way as many beans need to be created.
Please note that we have created all the spring boot controllers,services,repositorys across all projects under
package com.company.application
Below is the snippet of main class:
#SpringBootApplication
#ComponentScan(basePackages = {"com.company.application"})
public class RewardsApp extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(RewardsApp.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(RewardsApp.class);
}
}
/**
*Manual beans in RewardsApp
**/
#Bean
public SomeService someService()
{
return new SomeService();
}
By adding below annotation in RewardsApp.java did the trick for me, now autowiring was working for the classes inside the jars
#ComponentScan(basePackages = {"com.company"})
#EntityScan(basePackages = {"com.company"})
#EnableJpaRepositories(basePackages = {"com.company"})
I guess above are for Services,Entities(Domains),Repositories
How about having a configuration class (with relevant comp scans) for each module and importing those configs into your application class?
#SpringBootApplication
#ComponentScan(...)
#Import({RewardsContext.class, DBservicesContext.class})
...
Import docs here
I'm trying to create spring based application but after the build i'm getting exception while initializing the spring context -> No auto configuration classes found in META-INF/spring.factories.
I'm working heavily with spark in my application and i'm forced to use maven-assembly-plugin to package my jar (otherwise i'm unable to run spark job).
sample of my main class:
#SpringBootApplication
#EnableAutoConfiguration
public class MyMainClass {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(MyMainClass.class).web(false)
.run(args);
SparkJob job = ctx.getBean(SparkJob.class);
job.prepareJobAndRun();
ctx.close();
}
}
when i add
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mypackage.MyMainClass
everything works as expected, but i don't want to add them manually.
Any chance to make this work without the spring-boot-maven-plugin?
I was able to found out, that you can add your own META-INF/spring.factories to src/main/resources. This custom spring.factories will be then packed to jar. Tested, working.
The app I'm working on has a maven dependency on a common module containing a dozen spring-boot #Configuration beans specifying datasources, LDAP contexts, security modules, property sources etc which I often want to suppress.
My app and this common module are part of a spring-boot maven multi-module project. My sub-project needs about 6 of the 12 configuration beans.
I have got quite a long way using #Import and #SpringBootApplication#exclude and #ImportAutoConfiguration:
#Import({PropertySpringConfig.class,
LdapConfig.class,
SecurityConfig.class,
JpaDataConfiguration.class,
RestConfiguration.class,
WebConfigurer.class})
#SpringBootApplication(exclude = {
RefDataSourceConfig.class,
ElasticsearchAutoConfiguration.class,
CamelAutoConfiguration.class,
ElasticsearchDataAutoConfiguration.class})
public class MyRestApplication {
public static void main(String[] args) {
SpringApplication.run(MyRestApplication.class, args);
}
}
and a test configuration bean that all my JPA tests import (I have others, e.g. for REST tests):
#Configuration
#OverrideAutoConfiguration(enabled = false)
#ImportAutoConfiguration(value = {
CacheAutoConfiguration.class,
JpaRepositoriesAutoConfiguration.class,
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
TransactionAutoConfiguration.class,
TestDatabaseAutoConfiguration.class,
TestEntityManagerAutoConfiguration.class })
public class TestJpaConfiguration {}
The whole codebase was set up with Spring 1.3.x. I upgraded it to Spring 1.4.x.
Take for example one of the datasources, a configuration bean in the shared dependency - I don't need it, and it prevents Spring Boot autoconfiguration because it's marked with #Primary (possibly unnecessarily).
I don't want Spring Boot in my sub-project to see it when it runs autoconfiguration, but how do I share it from the common module with the other Spring Boot sub-projects that do need it?
I could split it out into its own maven project and only have it as a dependency in the sub-projects that needed it. But there are 11 other similar configuration beans! It could be seen as overkill although I like this approach - but I have 5 colleauges to convince.
I can just struggle on using #SpringBootApplication#excludes for the code and #ImportAutoConfiguration for the tests - but then I miss out on the Spring Boot benefits like #DataJpaTest or #JsonTest test slices
I could repeat the configuration beans in each project where they are needed - a bit of cut & paste - but I like this option the least.
Is there a 4?