2014-09-15 3 views
6

Я разрабатываю приложение Spring MVC. Когда я пытаюсь использовать AnnotationConfigApplicationContext в моем классе контроллера, я получаю следующую ошибку. Я не знаю, что именно это означает.AnnotationConfigApplicationContext еще не обновлен

@RequestMapping(value = "/generate", method = RequestMethod.POST) 
public ModelAndView generateMappingFile(@ModelAttribute Mapping mapping) 
{ 
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 
    MappingFileGenerator mfg = ctx.getBean(MappingFileGenerator.class); 
} 

Сообщение об ошибке ->

java.lang.IllegalStateException:org.spring[email protected]116b3c0 has not been refreshed yet 

Может кто-нибудь объяснить мне, что пошло не так здесь? Я использую Spring 4.0.1. Я новичок в Spring mvc.

+3

Почему вы создаете новый экземпляр в первую очередь ... В принципе, вы никогда не должны создавать новый экземпляр самостоятельно. Просто введите «MappingFileGenerator». Эта конструкция, которую вы используете сейчас, в конечном итоге приведет к плохой производительности, проблемам с памятью, транзакционным проблемам и т. Д. –

ответ

7

Когда вы создаете новый экземпляр ApplicationContext (независимо от того, какой тип), вы в основном создаете новые экземпляры каждого компонента, настроенного в этом ApplicationContext. Это хорошо в первый раз, он может работать второй и в зависимости от количества фасоли, после этого тип бобов будет падать. Поскольку контекст никогда не будет уничтожен (пока приложение не разбилось и не перезагрузится), вы столкнетесь с возможными проблемами памяти, проблемами производительности, странными транзакционными проблемами и т. Д.

Общее правило большого размера - never построить новый экземпляр ApplicationContext, но вместо этого использовать инъекцию зависимостей.

Если вы действительно хотите получить доступ к ApplicationContext, поместите поле этого типа в свой контроллер и положите на него @Autowired.

@Controller 
public class MyController { 

    @Autowired 
    private ApplicationContext ctx; 

    …. 

} 

Затем вы можете найти компонент, который вам нужен в методе. Это может быть удобно, если вы используете ApplicationContext в качестве фабрики для ваших бобов. Если вам нужны все бобы, то вам нужно просто вставить нужные вам компоненты.

@Controller 
public class MyController { 

    @Autowired 
    private MappingFileGenerator mfg ; 

    …. 

} 

Сейчас весна будет впрыскивать MappingFileGenerator и доступен для использования в своих методах. Не нужно создавать новый экземпляр ApplicationContext.

Дополнительная информация находится в Spring Reference Guide.

+0

Думайте * никогда * использование 'new ApplicationContext' может быть преувеличением? Spring предоставляет [примеры] (http://docs.spring.io/spring-amqp/reference/html/sample-apps.html#hello-world-sync) выполнение этого в методе 'main()'. –

+0

Хорошо, как общее правило (поскольку большинство приложений - это веб-приложения), он работает очень хорошо. Если у вас есть автономное приложение, оно отличается, но опять же вы должны создавать его только один раз и только один раз. –

2

@ Замечание M.Deinum получит еще несколько улучшений.

Подумайте о создании new ApplicationContext как о создании нового экземпляра приложения. Вы хотите сделать это каждый раз, когда это (или любой другой метод в указанная заявка) называется? Нет, нет.

Я угадываю вас думаю вы делаете, потому что вам нужен доступ к вашему ApplicationContext в этом методе. Для того, чтобы сделать что - то есть, чтобы получить доступ к работает контекст приложения (а не создавать новую), вы хотите сделать

@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); 
    } 

Ключевым моментом здесь является Autowired annotation, который говорит Spring для inject аннотированный объекта как dependency.

Я настоятельно рекомендую следующие ссылки, которые я включил (для начала), поскольку то, что вы здесь делаете, довольно убедительно указывает на то, что вы не обмотали голову тем, что DI и делает для вас, , использование его, скорее всего, будет контрпродуктивным по отношению к его собственным целям для вас.

+0

Это было очень полезно для понимания моей ошибки. Спасибо :) – KarthickN

+0

@KarthickN Вы не приняли мой ответ, когда я добавил последний абзац. Все в порядке - в любом случае, это лучший ответ. Но на самом деле ... читайте. DI может многое сделать для вас, но это большая концепция, чтобы понять, и пока вы не поймете ее на фундаментальном уровне, вы потратите много времени на то, чтобы вытащить свои волосы из-за ошибок, подобных этой, чем Spring или любой другой DI-система никогда не спасет вас. Ваш код также начнет давать гораздо меньше смысла (вам и всем остальным), что * противоположно точке DI * – drewmoore

+0

Извините за это .. Я думал проголосовать за оба ответа. Я не знал, что я не принял. Спасибо за ответ. Это было действительно полезно. Без обид. (Y) Да, как вы сказали, у меня появилось еще несколько новых проблем. Я работаю над этим:/ – KarthickN

Смежные вопросы