Programmatically configure Spring Boot app - spring

what's the easiest way to get the spring boot goodness but not try to autoconfigure all the things? For instance, to only run flyway with our already configured properties (some loaded via Consul + Spring Cloud), I was hoping I could do something like:
#Configuration
#Import({DataSourceAutoConfiguration.class, FlywayAutoConfiguration.class})
public class FlywaySetup {}
and have the main method just call SpringApplication.run(FlywaySetup.class)
The problem with this is it picks up all the Component Scan / crazy long list of other dependencies. Any way to specifically configure the dependencies (but still get the nicities of the framework)

If you run this app, it shouldn't use component scan at all. There's nothing that triggers component scan in spring boot besides #ComponentScan (that's available on #SpringBootApplication).
It would help if you could provide more accurate details rather than "crazy long list of other dependencies.". Running that FlywaySetup should only load those two configuration classes (important: these are not handled as auto-configuration anymore). If you have component scan, there's something else you're not showing.

You can exclude auto-configurations you don't need.
You may want to take a look at this SO answer to explore mechanism how to do that.

Related

How to make pf4j plugin beans injectable into Spring app

We are trying to utilize pf4j and pf4j-spring to provide a flexible application based on Spring.
Ideally, we would like to define Spring beans (#Service, #Repository and others) in plugins and inject them in the main application.
From what I can see, it seems to fail due to timing issues. Or in other words, Springs expects the beans to be available before the PluginManager gets instantiated.
There is an example repository that illustrates the issue on GitHub.
The question would be: Can I change something, so that Spring instantiates the PluginManager first? Is there another approach to make this work?
Note: Yes, we are aware of sbp. Unfortunately, it seems to be dead, and we didn't get it working properly either.

SpringBoot creating a framework starter library

I am creating a library using spring-boot (v2.1.6.RELEASE) as a starter project that will facilitate as base extension jar responsible for configuring and starting up some of the components based on client project properties file.
The issue I am facing is that if the client project's SpringBoot Application class contains the same package path as library everything works like charm! but when client project contains different package path and includes ComponentScan, it is not able to load or start components from the library.
Did anyone encounter this issue? how to make client application to auto-configure some of the components from library jar?
Note: I am following the library creation example from here: https://www.baeldung.com/spring-boot-custom-starter
There are many things that can go wrong here, without seeing relevant parts of actual code its hard to tell something concrete. Out of my head, here are a couple of points for consideration that can hopefully lead to the solution:
Since we use starters in our applications (and sometimes people use explicit component scanning in there spring applications) and this obviously works, probably the issue is with the starter module itself. Don't think that the fact that the component scan is used alone prevents the starter from being loaded ;)
Make sure the starter is a: regular library and not packaged as a spring boot application (read you don't use spring boot plugin) and have <packaging>jar</packaging> in your pom.xml or whatever you use to build.
Make sure you have: src/main/resources/META-INF/spring.factories file
(case sensitive and everything)
Make sure that this spring.factories file indeed contains a valid reference on your configuration (java class annotated with #Configuration). If you use component scanning in the same package, it will find and load this configuration even without spring factories, in this case, its just kind of another portion of your code just packaged as a separate jar. So this looks especially "suspicious" to me.
Make sure that #Configuration doesn't have #Conditional-something - maybe this condition is not obeyed and the configuration doesn't start. For debugging purposes maybe you even should remove these #Conditional annotations just to ensure that the Configuration starts. You can also provide some logging inside the #Configuration class, like: "loading my cool library".

How to disable Javers for integration tests?

I am using Javers 3.11.2 with Spring Boot 1.5.17. When I am trying to run integration tests on an embedded database I still see that Javers tables are getting created each time.
Is there a way I can disable Javers during these tests so that these tables will not be created each time?
There is the easy way, put:
javers:
sqlSchemaManagementEnabled: false
in your application-test.yml. See https://javers.org/documentation/spring-boot-integration/
Disclaimer: I've never used Javers.
In general, disabling something in "integration tests" means that you don't want to load some beans (of Javers in this case).
This means in turn that you have to exclude them from the list of configurations spring boot works with.
If you're using javers autoconfiguration module, it has to provide in its own "spring.factories" file (can be found inside the jar) a file for autoconfiguration.
Find its java code and see whether it has some "#Conditional on something (property beans, etc.)" If it has than create a profile for integration test that will configure the beans in a way that conditional in javers won't pass and the bean won't be created as a consequence
If it doesn't have a conditional on something like this, you'll have to exclude the whole configuration. Its usually can be done by annotation #SpringBootApplication(exclude=<JaversAutoconfiguration goes here>
This will, however, turn it off also for production usage, which is obviously not something that you want. So for "production" profile, you'll have to import it as a regular configuration (not an autoconfiguration), for integration test profile you won't need this.

Spring design pattern for common update service or module

I have a use case where I would like build a common interface or service which can update entities of application. Example case is shown as below:
Now every application has to handle update functionality of entities. Rather than implementing update functionality in n application module. I would like to build a common interface or server in spring boot.
Service will be like below:
My question is how to design service/interface which can used for above scenario. Any api or tool which can help me to achieve this. I dont want to write code for update in every application module.
Thanks in advance.
Last year I was thinking about the similar concept to yours, but in Apache Camel framework context. I haven't got enough time and motivation to do so, but your post encouraged me to give it a try - perhaps mostly because I've found your concept very similar to mine.
This is how I see it:
So basically I considered an environment with application that might uses N modules/plugins that enriches application's features, i.e. processing feature etc. Application uses module/plugin when it is available in the classpath - considering Java background. When the module is not available application works without its functionality like it was never there. Moreover I wanted to implement it purely using framework capabilities - in this case Spring - without ugly hacks/ifs in the source code.
Three solutions come to my mind:
- using request/response interceptors and modifying(#ControllerAdvice)
- using Spring AOP to intercept method invocations in *Service proxy classes
- using Apache Camel framework to create a routes for processing entities
Here's the brief overview of POC that I implemented:
I've chosen Spring AOP because I've never been using it before on my own.
simple EmployeeService that simulates saving employee - EmployeeEntity
3 processors that simulates Processing Modules that could be located outside the application. These three modules change properties of EmployeeEntity in some way.
one Aspect that intercepts "save" method in EmployeeService and handles invocation of available processors
In the next steps I'd like to externalize these Processors so these are some kind of pluggable jar files.
I'm wondering if this is something that you wanted to achieve?
link to Spring AOP introduction here: https://docs.spring.io/spring/docs/5.0.5.RELEASE/spring-framework-reference/core.html#aop
link to repository of mentioned POC: https://github.com/bkpawlowski/spring-aop

Facing issue while integrating CustomSpringUtilityJar in SpringBootApplication

I am having two spring applications and the details as follows:
1). Application One: This is a utility jar and its purpose is for CRUD operations on a specific table. We are using spring data jpa and hibernate for achieving the same. Since it is an utility this will not run alone
and it will be incuded as dependency to other applications. In this case we are using Application2 for that.
2) Application Two: This is a web service application made of Spring boot using yml configuration and also using Application One for CRUD operations on that table.
Issue: While running application Two(i.e. Spring Boot Application) , I am getting the error message related to the the components, repositories and entities of Application one,
as the bean is not registered in the configuration. Following are the approaches I used to solve thes:
Approach 1: In application 2, along with #SpringBootApplication annotation:
added Component Scan, Enity Scan and Enable JPA repositories and in these three annotations we have to include the package of both Application1 and Application2.
This scenario is working fine.
Note: I am not using Approach 1 as I have to make these three changes in every service applications which is going to use this utility jar. So decided to proceed with Approach2
Approach 2: Created an custom annotation like #UtilJar annotation and configuration class in Application1 and in that configuration class, added the three
annotations along with the configuration annotation.
In this case, while adding the custom annotation(created from Application1) in Application2, all the components and repositories registered in Application1 is registered and error is
showing related to the repositories registered in Application 2 . The only way I can solve on this is to give EnableJPARepository in Application2 which again similar to
Approach1.
So the root cause what I understood is because of #EnableJPARepository annotation given in the Application1 prompted for this error in Application2. Can anyone suggest me how to proceed on this.

Resources