How to make sure Flyway loads before my bean? - java

I have a Spring Boot application in which a Bean loads configuration-data from the database.
Right now I set up this Bean in the Configuration class. But it seems it loads before Flyway.
How to make sure Flyway has finished it's job before my beans get loaded?

You can initialize it before you start Spring Boot application:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
// Init Flyway here
SpringApplication.run(Application.class, args);
}
}
Second option is to use #DependsOn annotation for your beans depending on Flyway.

Related

Spring Boot YAML binding: fail when using yml extension

i cannot start my spring-boot application, because an exception with the following messagge is thrown"Error creating bean with name 'application': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'tracer.datadog' in value
The reason is that spring-boot cannot find the "tracer.datadog" prop specificied on the application class:
#SpringBootApplication
#EnableMongoAuditing
public class Application {
#Value("${tracer.datadog}")
private boolean datadog;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#PostConstruct
private void jaegerTracer() {
if (!datadog) {
GlobalTracer.registerIfAbsent(Configuration.fromEnv().getTracer());
}
}
}
But that property is correctly defined over the application.yml file:
tracer:
datadog: true
However, changing the extension to .YAML spring-boot "find" the file and the application starts fine.
Does anyone can tell me how can i do to solve this problem and use the .yml extension? using the .yaml extension is not a possibility because of company standards

Is it possible to exclude nested configuration from autoconfiguration in Spring Boot application?

Suppose we have a Spring Boot application and autoconfiguration with several configurations defined inside it
#Configuration
#AutoConfigureBefore(MainAutoConfiguration.class)
public class TestAutoConfiguration {
....
#Configuration
public static class FirstNestedConfiguration {
...
}
#Configuration
public static class SecondNestedConfiguration {
...
}
}
this class is providing via external library dependency and all conditions are satisfied, so all beans in these configurations are loading.
Nevertheless, I need to exclude beans provided in FirstNestedConfiguration
Is it possible to do it?
UPD: as it's simple Spring Boot application, it runs as
#SpringCloudApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
without any explicit #ComponentScan configuration
You might use excludeFilters in #ComponentScan like this:
#ComponentScan(value = {'your.package'},
excludeFilters = #Filter(TestAutoConfiguration.class))
Also, if you want to exclude specific autoconfiguration globally, use properties:
spring:
autoconfigure.exclude: your.package.TestAutoConfiguration
However, please, note that this way you exclude outer configuration. According to this issue it's not possible to exclude inner configuration.
Does the profile approach works for you?
Look for With the #Profile annotation section
#Profile("ConfigOne")
#Configuration
Configuration spring documentation

How to create a multi module spring mvc application

I have 2 maven packages, both of them with spring boot dependencies.
CoreApplication and CustomerApplication. Both apps have Spring MVC controllers, views and static resources.
In CoreApplication I dont have any runner class annotated with #SpringBootApplication.
In CustomerApplication pom.xml I use CoreApplication as a dependency.
If I run the CustomerApplication #SpringBootApplication annotated runner class, it finds the controllers in CoreApplication, but not the views. It can serve requests like http://localhost:8080/core/index, but I get an error from thymeleaf. (org.thymeleaf.exceptions.TemplateInputException: Error resolving template "index")
Is it possible what I want to do? How can I have a Core module with all common app specific stuff and a Customer app for every customer with their own business logic?
Maybe you can try:
Annotate your CoreApplication module with #SpringBootApplication to let Spring manage and initialize your app as usual:
#SpringBootApplication
public class CoreApplication {
public static void main(String[] args) {
SpringApplication.run(CoreApplication.class, args);
}
}
And in your CustomerApplication's runner, you can put:
#SpringBootApplication
public class CustomerApplication {
public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(CoreApplication.class, CustomerApplication.class)
.run(args);
}
}
This way Spring will initialize your two modules properly.

EnableWebMvc throws ServletException: Could not resolve view with name

Playing around with Spring Boot + MVC with static HTML pages, while noticed this thing:
Firstly, what I have:
Index controller:
#Controller
public class IndexController {
#RequestMapping("/")
public String index() {
return "index.html";
}
#RequestMapping("/{path:[^\\.]+}/**")
public String forward() {
return "forward:/";
}
}
The Html file is:...\src\main\resources\static\index.html
So when my main application class is:
#SpringBootApplication
public class MyApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Everything works well and in default path: localhost:8080\ I get index.html page content
But if I annotate Application class with #EnableWebMvc
#SpringBootApplication
#EnableWebMvc
public class MyApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
I get exception: javax.servlet.ServletException: Could not resolve view with name 'index.html' in servlet with name 'dispatcherServlet'
But according to this spring doc it is a valid configuration.
Maybe someone can explain me why? Do I understand something wrong?
According to spring-boot's docs
The auto-configuration adds the following features on top of Spring’s defaults:
Static index.html support.
...
If you want to keep Spring Boot MVC features, and you just want to add
additional MVC configuration (interceptors, formatters, view
controllers etc.) you can add your own #Configuration class of type
WebMvcConfigurerAdapter, but without #EnableWebMvc. If you wish to
provide custom instances of RequestMappingHandlerMapping,
RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you
can declare a WebMvcRegistrationsAdapter instance providing such
components.
So by adding #EnableWebMvc you just disable what spring-boot autoconfiguring for you. Namely static index.html support.
Actually I think when you choose to use spring boot you should use the default config of spring Boot. It means you just have to edit the file application.properties. Now if you use spring mvc, you have to provide your own servlet. So I think mixing up the to is not a good idea. Either you use spring Boot wiht no much config to do or you use spring mvc and you make all the necessary config.
According to Spring Boot MVC structure, you should locate your html file in the templates folder. Then will be visible for Spring Boot
src\main\resources\templates\index.html

Spring or Spring Boot integration with legacy codebase

given an existing, non-Spring based code, is it possible to wire together dependencies using Spring without changing how the other parts of the code work? In particular, most Spring/Boot examples call SpringApplication.run in the main, like this:
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
I can't do this, I just want Spring Boot to wire dependencies when a certain method (getter) is called. Is this possible?
Thanks.

Categories