I'm reading through Spring Integration documentation and I still can't get into one thing: does Spring resolve all dependencies and make that automagic IoC dependency injection at compile time or at runtime?
I believed that it is runtime job to wire available components together in a data route from gateway to some data endpoint (e.g. DB). But since most of examples are made using DSL syntax in java, it seems that it's a compile time job.
So, glueing together beans in a data highway can be made only at compile time?
Summing up my comments here :
1) Spring IOC container manages beans from its creation till destruction. What this means is the beans are ready in sort of a bucket, which is a ready to use application. Thus, it is necessary to create the contents of the bucket at compile time, rather then runtime. This does not include hot-swapping of beans.. I hope this is what you were looking for.
2) You can create as many routes as you want, those all beans will be put in the container.... And as far as I understand, you cannot just change your source code and synchronize it with already running one, you have to atleast do a graceful restart. There is a bottom line to this, Spring must see if all beans are properly autowired, no circular dependencies, and there is no expectation of source code during run time. Sure you can get your beans via RMI, but that doesn't count as you have declared it already. So yes, compile time it is
The java DSL syntax is simply a different way of defining a flow definition (a series a bean definitions). The beans are still created and wired together during application initialization (runtime).
Related
One of the main advantage of using spring dependency injection is for testing the functionality using same interface with different implementation without making any changes in the code, that is through injecting these different implementations(dependencies) in configuration file.
Lets take an example where we have developed our application with java configuration/annotation based (No .xml files at all).
We have done a code freeze and have deployed the code in server.
Now for a QA team to perform testing they need to inject different implementations for the interface by making changes in configuration file without touching code.
If its a .xml file, devOps team can inject the different implementation by injecting that bean name and can restart the server.
But since we have used the annotations based/java based configuration, How can we achieve this ?
Thanks in advance.
One of the main advantage of using spring dependency injection is for
testing the functionality using same interface with different
implementation
One of main advantages of Spring is indeed the dependency injection facility.
But you will also find very often cases where you have beans with a single implementation :
beans that rely on an interface but there is only one implementation for it.
bean that don't rely on any interface but are straight classes that you want to turn into injectable beans.
We have done a code freeze and have deployed the code in server. Now
for a QA team to perform testing they need to inject different
implementations for the interface by making changes in configuration
file without touching code.
Spring and more generally dependency injection pattern/frameworks are not designed to perform hot swapping or implementation modification of a deployed component without repackaging the component.
At startup, Spring creates its context and loads all required beans for the application in its container.
If you want to change configurations of some beans, the most clean and side effect less way is destroying the spring context/container, repackage the application with the needed changes and restart it.
If its a .xml file, QA team can inject the different implementation by
injecting that bean name and can restart the server.
Ideally, the QA team should test the implementation that you deploy in QA env and that will be used by final users to stay the closest of the real functioning of the application.
Now, if because of some specific constraints, some components to test by the QA should be mocked/stubbed in a some way, just create a different build for that.
Spring Boot Profile and Maven Profile features can help for.
I'm working in a webapp and this is the first time that I'm using Java based configuration. I have a bunch of class to configure all:
ApplicationContext
PersistenceContext
SecurityContext
WebAppInitializer
WebMvcContext
Now I'm defining Spring Data repositories and the service layer so I need to inject the repositories there. Normally I would use Autowired but I've read that it is preferable to define the injections manually so the question is, where?
Maybe neither of the previous configuration classes is suitable for such task but, do I have to create a single class to define all the injections or is better to have on for each function? What happens if the project grows too much?
I think that the main question would be what is best way to organize dependencies in a Spring project. What do you do?
I add here an image of the structure of the project as a petition. I'm trying to decouple layers and now I need to inject UserRepository to UserService.
No, I would not define a single class to do all the injections. All your classes are coupled that way.
I don't understand what "define the injections manually" means. You have to specify them in either XML or annotations. There's no other way that I know of.
You don't say if you're using XML or annotation configuration. I find myself using the latter more of the time, with only enough XML configuration to tell the Spring app context to scan for annotations.
The Spring idiom would have you specify your configuration in layers if you're using XML. It's a moot point for annotations, because they go into your source code.
Your application will read the Spring context on start up, instantiate all the beans, and wire together the necessary dependencies. You're good to go from then on.
I disagree with the link you provided. Avoid autowiring? No.
The article said that he recommends using XML configuration for large projects. This is a very small project at this point. It seems to me that auto wiring with annotations would be fine even by the article's author's words.
i am working on a really big enterprise application, with couple of thousand beans, and a big dependency graph between classes. We are using Spring 3, with #Autowired fields (autowiring in constuctor).
I am trying to create an integration test for one of the controllers, which has multiple dependencies, each of those with more dependencies, etc. It is borderline impossible to create an xml definition of the classes which needs to be resolved because of the bad project structure and dependency graph - therefore i cant build the ApplicationContext...
What i am trying to do is to scan for fields in a class, and if they are beans (Component, Service, etc), add them to the ApplicationContext from the code.
I could iterate through the class' fields in a recursive function with relfection i guess, and add the beans to the appcontext, but i have no idea how...
How can i do this? Is this feasible?
Unless I am missing something, you're trying to solve the wrong problem. If your module structure is in that state, trying to build the context dynamically is not going to help you because ultimately you're going to load pretty much the whole application.
I would advise you to create a common "low-level" stack for your app: something that is reasonable and clearly identified by separate modules. Once you have that, start creating boundaries for major features and try to load only them.
If you can't do that, you can still load a test application context by using mocks to cut dependencies in your graph. In any case, discovering the fields to wire along the way is not going to buy you anything.
My application can't start up, if the PostgreSQL database it's using has not started up yet (the delay between the two is ~2 minutes). It's a fairly complex inherited project and I can't fiddle with the configuration too much.
My idea would be to have a bean that runs as the first thing in the Spring container. I've tried to configure it with annotations (#PostConstruct) and in xml (<bean id="dbStartupMonitor" class="ee.package.monitoring.DBStartupMonitor" init-method="checkConnection" lazy-init="false" />), but in neither of these cases the checkConnection() seems to be running (no logging appears). In addition, how can I make sure that this bean is created first?
Now, regarding the checkConnection(), the idea would be to check if the database is up. If it's not, sleep for some amount of time and try again. This needs to block the rest of the initialization of the Spring MVC container, but I'm pretty sure it doesn't work that way.
Is it even possible to solve it like this?
The problem was the order of bean initialization. The datasource-dependent beans were initialized first, so after some substantial digging in the bean configuration xml files, I added the depends-on attribute with my DB monitor bean. This ensures that the monitor is initialized first.
Also, the initialization method (init-method) does block, so the "check-sleep-check until database is up" cycle works fine.
This is one of those strange questions where people would ask - why?
So I will start with why I would like to do this and then go into the issue. I would like to have more control over how the spring context is loaded. For example, I do not want to load the domain and web-api at the same time. That would make the resources available before their dependencies are ready.
There might also be that I need to check the state of something before I can continue this process. So to say, there will be sequential order between modules/contexts. Maybe not just booting but also in shutdown.
So the issue is that I can't find any information on how to load the domain-context, then when that is finished I would check the state and lastly load the api-context. I would like to do all of this from java-code as I need to control the flow of the start up. I have basics working with SpringServlet loading the web-context. What I have not found any information on is if it is possible to load a context, wait and load another context that refers to the first one.
It might be good to know that I am not using JavaEE nor a container. I am only using embeddded Jetty with servlet and spring. So is there a way this can be done?
I'd suggest to consider following:
Read SmartLifeCycle and Phased for extension points on the order of application context life cycle management. The idea is that you have your top-level important beans implement the interfaces such that the standard application context initialization will be also handled to those beans in the order that you customize.
Break your application context XML files into smaller pieces. Use <import /> in the ones that depend on a higher/lower context.
Use depends-on attribute on your mission critical beans to ensure the dependencies.
Use InitializingBean on the ones that you need to make sure a dependency is satisfied for the current bean after it's initialized.
Consider lazy loaded beans and Lazy Proxy.
So the bean will be created only on first usage ...