I'm a noob when using Spring and I have a doubt.
When and where must I initialize the spring context?
Right now I am initializing the context when I'm going to use something like a properties file:
ClassPathXmlApplicationContext cxt = new ClassPathXmlApplicationContext("myContext.xml");
But I have read that the Spring context must be initialized in the entry point of my program (Main.java) and pass it as argument in the necessary methods.
Is this true?
As #MarounMaroun said, it really depends on what are you trying to do.
When people use Spring they usually build the entire application to take advantage of what Spring has to offer. That is to say, they put everything in the Spring context, configure it, and let it wire all the things together when starting. So in order to be useful, the application needs to load the Spring context before doing anything else.
For a standalone application you do the initialization in the main method.
When main is called, you first initialize the Spring context, and once the context is fully loaded you retain a reference to it and make it available where needed.
If it makes sense to initialize the Spring context at a later time or in another class you can do that too, but as I said, most applications need the context initialized to be able to function so that's why they initialize it as early as possible, in the main method, and that's probably the recommendation you have read.
If you are talking about a web application, you should do it web.xml
Loading context in Spring using web.xml
If it's a test, things are different:
spring junit load application context for tests
In both cases, you don't need an explicit main.java
Related
I want to initialize some business logic (e.g. send some messages to a message broker) in a Spring Boot application after context is created and beans (singletons) are initialized - what is the "most correct" place for it?
From my perspective the candidates are:
Implement ApplicationListener + listen for ContextStartedEvent
ApplicationRunner's OR CommandLineRunner's run() method
#PostConstruct of a particular bean (I don't this method, but have seen sometimes in colleagues' code - because I need to be sure all beans are created, initialized, customized, set up, etc. and I don't wanna play with beans load order)
I understand that in general, in MVC web application the place for business logic is #Service, but I need to call it immediately after the start of my application, so what's the best way to do that?
I would go with #EventListener. Like you said there are different ways to achieve this. I will give my opinion on your numbers
ApplicationListener called 3 times. No need to listen this one. This maybe usefull if you are doing something close to tomcat.
ApplicationRunner,CommandLineRunner is called after all bean initialization. This can be useful.
#PostConstruct you can get null beans if you are working with other components.
I prepared a small example to use all these in one application and print some logs but I could not put them here. spring log looks ugly here. anyway my suggestion is here if you dont have any dependency to other beans this looks nicest. if there are dependencies then you can use ApplicationListener which was the last logged in my example.
Is there a way to inject/import spring-managed class into a legacy code or non-spring class?
I am working on a spring project, but we have this legacy code that needs access to a spring managed class (specifically a jparepsository implementation class). Is this possible?
Sorry, I am a newbie in the Spring framework. Any help/advice will be greatly appreciated. Thanks :)
You can always load an application context up in your code. It's a simple matter of doing something like this:
ApplicationContext context = new ClassPathXmlApplicationContext("path/to/applicationContext.xml");
You'll have access to all the beans created there via the getBean() function. This may be sufficient for you. However, you won't be accessing the same context as other parts of your application, you'll have a copy. So if you have stateful beans in your application context the "unmanaged" code won't see the same state.
if you're talking about a web application, then you can use the WebApplicationContextUtils to access the same context as the rest of the web applicatiom.
WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
Since you have access to the legacy code, what prevents you from rewriting it to be spring managed, or at leas to be ApplicationContextAware?
I have a spring MVC project, in one of the controllers, i have a DB connection object that needs to be initialized only once in the controller, what is the best approach to follow when adding this initialization code, for now, i used a static block in the controller where i added the initialization code, do u have any other suggestions.
thanks in advance
Make it a Spring bean. That way it's a singleton (by default), and can be injected wherever you want.
Note that even if you leave its initialization in the controller, making it static is useless, since a controller is also a Spring bean, which is a singleton by default.
Well in spring you don't need to initialize the db connections yourself , It provide support for db connections
You just need to specify the the bean in .xml files and directly autowired that bean into your controller
use dao pattern to implement database connections see some example it will be easy container will manage db connections object life cycle for you
Thanks,
Himanshu
May I recommend you read the Spring reference guide for Object Relational Mapping and Data Access? Its quite comprehensive and details how to set up a data source, session factory, implement DAO classes, transaction management etc... Hopefully you will find this is a good place to start.
I am a newbie and going through spring learning curve and i have a question to understand what cases i will be using code based servlet container initialization against xml initialization in web descriptor file.
The reason for my question is, at this time i wanted to spend time in learning what is used most of the time rather overloading many concepts which might be provided with the framework just for flexibility.
Any advice?
Thanks for reading
The main reason you'd want to use Java based container initialization is when you want to register Spring managed Servlet, Filter, and XxxListener objects.
For example, when you want to register a ServletContextListener, you specify
<listener>
com.your.listeners.MyListener
</listener>
in the deployment descriptor. The container takes that fully qualified class name and uses reflection to find the corresponding Class object which it instantiates to get an instance. In other words, the object is uniquely managed by the container. You can't have Spring inject fields easily.
On the other hand, with a ServletContainerInitializer, or the corresponding Spring class, you can specify Servlet, Filter, or Listener beans in your Spring context (either through XML or #Configuration classes) and register those Spring-managed instances directly through the ServletContext.
Note that there are still some configurations for which you need to use the deployment descriptor.
I a get a get a bean from Spring container say
MyClass obj1 = Context.getBean("obj1");
After using obj1, I am sure that it will not be needed in rest of my application.
Then is there any way to ask Spring container to destroy the bean.
Atleast giving hint to Spring container that it is no more needed and spring my decide whether to destroy it or not (Similar to garbage collection)?
Make "obj1" a prototype-scoped bean. Then Spring will create a new instance of it each time you ask for it (make sure you are ok with this), and then it will not manage the instance any further, so when you are done with it and release all your references it can be garbage collected.
Prototype scope is like new, only giving you Spring-configured beans.
I don't think it will be possible for you to tell Spring container to destroy that bean. If you notice most of these beans created by Spring framework are Singleton that are supposed to give you same instance of the bean every time you get it injected into your code. A singleton by nature is supposed to live through the life of the application hence it cannot be destroyed.