I am developing a spring MVC application. When I try to use AnnotationConfigApplicationContext in my controller class I am getting the following error. I have no idea what this statement exactly means.
@RequestMapping(value = "/generate", method = RequestMethod.POST)
public ModelAndView generateMappingFile(@ModelAttribute Mapping mapping)
{
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
MappingFileGenerator mfg = ctx.getBean(MappingFileGenerator.class);
}
Error Message -->
java.lang.IllegalStateException:org.springframework.context.annotation.AnnotationConfigApplicationContext@116b3c0 has not been refreshed yet
Can someone explain me what went wrong here ? I am using Spring 4.0.1.. I am new to spring mvc.
When you are creating a new instance of an ApplicationContext
(regardless which type) you are basically creating new instances of each and every bean configured in that ApplicationContext
. That is nice the first time, it might work the second and depending on the amount of beans, the type of beans will crash after that. As the context will never be destroy (until the app crashed and is restarted) you will run into possible memory issues, performance issues, strange transactional problems etc.
A general rule of thumb is to never construct a new instance of an ApplicationContext
but to use dependency injection instead.
If you really want access to the ApplicationContext
put a field of that type in your controller and put @Autowired
on it.
@Controller
public class MyController {
@Autowired
private ApplicationContext ctx;
….
}
Then you can do a lookup for the bean you need in the method. This can be handy if you use the ApplicationContext
as a factory for your beans. If all the beans you need are singletons it is better to simply inject the bean you need.
@Controller
public class MyController {
@Autowired
private MappingFileGenerator mfg ;
….
}
Now Spring will inject the MappingFileGenerator
and it is available for use in your methods. No need to create a new instance of an ApplicationContext
.
More information is in the Spring Reference Guide.
@M.Deinum's comment will get quite a few more upvotes.
Think of creating a new ApplicationContext
as instantiating a new (instance of an) application. Do you want to do that every time this (or any other method in said application) is called? No, you don't.
I'm guessing you think you do because you need access to your ApplicationContext
in this method. To do that - i.e. to get access to the running application context (rather than creating a new one), you want to do
@Controller // or @Service / @Component / ... : tells Spring that this is a bean, and to inject the specified dependencies
class YourClass {
@Autowired // tells Spring that this object is a dependency should should be injected
ApplicationContext ctx;
@RequestMapping(value = "/generate", method = RequestMethod.POST)
public ModelAndView generateMappingFile(@ModelAttribute Mapping mapping) {
MappingFileGenerator mfg = ctx.getBean(MappingFileGenerator.class);
}
The key here is the Autowired
annotation, which tells Spring to inject the annotated object as a dependency.
I highly suggest following the links I've included (for starters), as what you're doing here suggests pretty strongly that you haven't wrapped your head around what DI is and does for you, and until you do, using it is likely to be counterproductive toward it's own ends for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With