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.
Related
There are many examples and documentations about #Lazy. Maybe I didn't get the point, but why should it ever be used? Instantiating a bean costs < 1 ms at startup. Using lazy loading for beans gives you a bunch of new integration tests. Furthermore it could be rather dangerous, when your application starts up with no errors and crashes on the first call to a lazy loaded bean. So why? Does anybody has got a good example?
Lazy initialization might be useful, when your #Lazy annotated component depends on some infrastructure to be properly initialized. So, for example, if you have a component which needs to download some files during startup, then it probably makes a lot of sense to annotate it with #Lazy. This way it doesn't try to download files (which takes a lot of time) when it's not going to be used for a while.
However, personally I think using lazy components often leads to a bad design. Think twice before you use it.
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).
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 ...
Hey, I'm wondering why class load breakpoint is not working in this case. Whenever I set it up and load spring context, it is not triggered. Any idea what might be the reason ?
Debugging spring beans is no different than any other object. In fact 5 seconds ago I was debugging a spring bean. So the problem is somewhere else - perhaps your breakpoint is not reached.
My model layer is being used by a handful of different projects and I'd like to use a single XML Spring Configuration file for the model regardless of which project is using it.
My question is: Since not all beans are used in all projects am I wasting resources to any significant amount if there not being instantiated? I'm not too sure how lazy Spring is about loading them since it's never been an issue until now.
Any ideas?
Taken from the Spring Reference Manual:
The default behavior for ApplicationContext implementations is to eagerly pre-instantiate all singleton beans at startup. Pre-instantiation means that an ApplicationContext will eagerly create and configure all of its singleton beans as part of its initialization process. Generally this is a good thing, because it means that any errors in the configuration or in the surrounding environment will be discovered immediately (as opposed to possibly hours or even days down the line).
However, there are times when this behavior is not what is wanted. If you do not want a singleton bean to be pre-instantiated when using an ApplicationContext, you can selectively control this by marking a bean definition as lazy-initialized. A lazily-initialized bean indicates to the IoC container whether or not a bean instance should be created at startup or when it is first requested.
When configuring beans via XML, this lazy loading is controlled by the 'lazy-init' attribute on the [bean element] ; for example:
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>
But, unless your beans are using up resources like file locks or database connections, I wouldn't worry too much about simple memory overhead if it is easier for you to have this one configuration for multiple (but different) profiles.
In addition to the other comments: it's also possible to specify a whole configuration file to be lazily initialized, by using the 'default-lazy-init' attribute on the <beans/> element; for example:
<beans default-lazy-init="true">
<!-- no beans will be pre-instantiated... -->
</beans>
This is much easier than adding the lazy-init attribute to every bean, if you have a lot of them.
By default Spring beans are singletons and are instantiated when the application context is created (at startup). So assuming you haven't overridden the default behaviour, then a single instance of every bean will be created.
Depends upon the objects.
But, unused code is 'cruft' and will increase the cost of maintenance.
Better to delete the refs and classes. You can always restore from version control if they are needed later.