2014-09-15 2 views
6

나는 봄 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 

사람이 잘못 여기에 무슨 일이 있었는지 나를 설명 할 수 있습니까? 나는 봄 4.0.1을 사용하고있다. 나는 봄 mvc에 새로운 사람이다.

+3

왜 처음부터 새 인스턴스를 만드십니까? 기본적으로 새 인스턴스를 직접 만들어서는 안됩니다. 그냥'MappingFileGenerator'를 주입하십시오. 당신이 지금 사용하고있는이 구조는 결국 나쁜 성능, 메모리 문제, 트랜잭션 문제 등을 초래할 것입니다. –

답변

7

ApplicationContext의 새 인스턴스를 만들 때 (어떤 유형이든 관계없이) 기본적으로 ApplicationContext에 구성된 모든 빈의 새 인스턴스를 만듭니다. 처음에는 좋았습니다. 두 번째로 작동 할 수도 있고 콩의 양에 따라 콩 종류가 충돌합니다. (응용 프로그램이 충돌하고 다시 시작할 때까지) 문맥이 파괴되지 않습니다로서 당신은

엄지 손가락의 일반적인 규칙은에 결코 새로운 인스턴스를 생성 등 가능한 메모리 문제, 성능 문제, 이상한 거래 문제로 실행됩니다 ApplicationContext이지만 종속성 주입을 대신 사용하십시오.

ApplicationContext에 액세스하려면 컨트롤러에 해당 유형의 필드를 입력하고 @Autowired을 입력하십시오.

@Controller 
public class MyController { 

    @Autowired 
    private ApplicationContext ctx; 

    …. 

} 

그런 다음 메소드에서 필요한 bean을 찾을 수 있습니다. 빈의 팩토리로 ApplicationContext을 사용하면이 방법이 유용 할 수 있습니다. 필요한 콩이 모두 싱글 톤이라면 필요한 콩을 단순히 주입하는 것이 낫습니다.

@Controller 
public class MyController { 

    @Autowired 
    private MappingFileGenerator mfg ; 

    …. 

} 

이제 봄은 MappingFileGenerator 주입하고 당신의 방법에 사용하기 위해 사용할 수 있습니다. ApplicationContext의 새 인스턴스를 만들 필요가 없습니다.

자세한 내용은 Spring Reference Guide에 있습니다.

+0

생각해 보지 마세요 * 새로운 ApplicationContext를 사용하면 결코 과장 될 수 있습니까? Spring은'main()'메소드에서 이것을 수행하는 [examples] (http://docs.spring.io/spring-amqp/reference/html/sample-apps.html#hello-world-sync)를 제공한다. –

+0

일반적으로 (대부분의 응용 프로그램은 웹 기반 응용 프로그램이므로) 잘 작동합니다. 독립 실행 형 응용 프로그램이있는 경우에는 다르지만 다시 한 번만 만들어야합니다. –

2

@ M.Deinum의 의견은 꽤 많은 upvotes를 얻을 것입니다.

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

여기서 핵심은 inject 주석 객체에 봄을 알려주는 Autowired annotation입니다 싶지 dependency으로

제가 처음에 포함시킨 링크를 따라하면 좋습니다. 여기서하고있는 일은 DI가 무엇인지에 대해 머리를 싸지 않고, 할 때까지 , 그것을 사용하는 것은 당신 자신의 목적에 대해 비생산적인 경향이 있습니다.

+0

그건 내 실수를 이해하는데 정말로 도움이되었습니다. 고마워요 :) – KarthickN

+0

@ KarthickN 마지막 단락을 추가 할 때 내 대답을 받아 들일 수 없습니다. 괜찮습니다. 어쨌든 더 나은 대답입니다. 그러나 실제로 ... 독서를하십시오. DI는 당신을 위해 많은 것을 할 수 있지만 이해하는 것은 큰 개념입니다. 그리고 당신이 근본적인 수준에서 그것을 이해할 때까지는 Spring이나 다른 어떤 것보다이 오류와 같은 오류에 당신의 머리카락을 끌어들이는 데 더 많은 시간을 낭비 할 것입니다 DI 프레임 워크가 당신을 구할 것입니다. 당신의 코드는 DI의 시점과 반대입니다. * – drewmoore

+0

죄송합니다. 나는 두 가지 대답 모두에 투표 할 생각입니다. 나는 내가 받아 들일 수없는 것을 안다. 대답 해 주셔서 감사합니다. 정말 도움이되었습니다. 불쾌감이 없습니다 (예) 네가 말했듯이 나는 새로운 문제가 좀있다. 나는 그것에 대해 연구 중이다 :/ – KarthickN

관련 문제