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.
Related
I am trying to use Apache Camel File-Watch feature.
However I notice all example are used along with Spring.
Is there anyway to make use of this feature without Spring ?
Thank you for any potential input.
Best regards.
Apache Camel is a standalone integration framework to easily integrate different systems using well know and established EIP (Enterprise Integration Patterns).
It is not tied to Spring in any way at its core and has different deployment / integration models out of which is Spring / Spring Boot for the sake of easing its adoption and configuration for Spring framework users.
Out of the runtime contexts, you can use for example Camel Main component to run your application having a File Watch component setup to watch the /tmp/ directory change events:
The main application would look like the following:
public class FileWatchApplication {
private FileWatchApplication() {
}
public static void main(String[] args) throws Exception {
// use Camels Main class
Main main = new Main(FileWatchApplication.class);
// now keep the application running until the JVM is terminated (ctrl + c or sigterm)
main.run(args);
}
}
A simple RouteBuilder setting up your File Watch component would look like the following (note that it must be within the same (or child) package of the FileWatchApplication class):
public class FileWatchRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
// snippet configuration from the official documentation
from("file-watch:///tmp/")
.log("File event: ${header.CamelFileEventType} occurred on file ${header.CamelFileName} at ${header.CamelFileLastModified}");
}
}
Camel is based on Spring. In fact, the Camel Context is an extension of the Spring Application Context. So if you have Camel, you also must have Spring.
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.
With Spring's AbstractRefreshableApplicationContext, I am able to force Spring to fail if there is a conflict in Bean IDs or circular references by setting a couple of flags and refreshing the context like so:
AbstractRefreshableApplicationContext refreshableContext;
...
refreshableContext.setAllowBeanDefinitionOverriding(false);
refreshableContext.setAllowCircularReferences(false);
refreshableContext.refresh();
However, Spring Boot returns a ConfigurableApplicationContext which is not an instance of AbstractRefreshableApplicationContext and does not appear to have any means to prevent bean definition overriding or circular references.
Does anyone know of a way and have an example of how to prevent these types of conflicts?
For context, this is for a large project that has a mix of annotated and xml defined beans. The version of Spring Boot used is 1.3.1.RELEASE. There have been some cases where folks added duplicate bean definitions in the xml, but the application started up fine and wasn't immediately apparent the original bean was overridden until run-time issues started occurring.
The goal here is to prevent the application from event starting up if such a conflict occurs. From various forums I know Spring IDE can detect these, but the desire is to enforce this in the CI build which is a stronger safety net.
After some searching, I can't find any support for this in the context that Sprint Boot returns. If this can't be done through the context, is there a different solution available?
Thanks in advance.
You may use an initializer when building your Spring Boot app:
#SpringBootApplication
public class SpringBootApp {
public static void main(String... args) {
new SpringApplicationBuilder(SpringBootApp.class)
.initializers(new ApplicationContextInitializer<GenericApplicationContext>() {
#Override
public void initialize(GenericApplicationContext applicationContext) {
applicationContext.setAllowBeanDefinitionOverriding(false);
}
})
.run(args);
}
}
Or with java 8:
new SpringApplicationBuilder(SpringBootApp.class)
.initializers((GenericApplicationContext c) -> c.setAllowBeanDefinitionOverriding(false) )
.run(args);
add below into your application.yml
spring.main.allow-bean-definition-overriding: false
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.
Say I just want to have a simple Java executable (executable JAR) use Spring XML for dependency injection. I don't want any other Spring JARs or functionality (i.e. Spring MVC, Spring Batch, etc.). I simply want to use Spring for dependency injection and nothing more.
What are the bare bones minimal JARs I need on the classpath, and implementation I need to set up in my main Driver class (see below) to read a myapp-config.xml off the runtime classpath and inject the "roots" of my dependency tree?
public class Driver {
private Widget widget;
public static void main(String[] args) {
Driver driver = new Driver();
driver.start();
}
public void start() {
// By this point, the widget instance should have been injected by Spring.
widget.doSomething();
}
// Getter & setter for widget.
}