Spring 현재 ApplicationContext 가져 오기


105

내 웹 애플리케이션에 Spring MVC를 사용하고 있습니다. 내 콩은 " spring-servlet.xml"파일에 기록 됩니다.

이제 클래스가 MyClass있고 스프링 빈을 사용 하여이 클래스에 액세스하고 싶습니다.

에서 spring-servlet.xml내가 작성한 다음

<bean id="myClass" class="com.lynas.MyClass" />

이제 나는 이것을 사용하여 액세스해야합니다 ApplicationContext

ApplicationContext context = ??

내가 할 수 있도록

MyClass myClass = (MyClass) context.getBean("myClass");

이 작업을 수행하는 방법 ??


3
@Autowired MyClass myClass가 작업을 수행해야합니다!
Mannekenpix 2014

답변:


161

주입 만하면 ..

@Autowired
private ApplicationContext appContext;

또는이 인터페이스 구현 : ApplicationContextAware


아마도 이것이 작동 할 수 있습니다 : stackoverflow.com/questions/11682858/…
gipinani

다음 ApplicationContextProvider.java답변이 이에 대한 가장 신뢰할 수있는 솔루션으로 보입니다.
Ionut

1
매번 NULL을 반환합니다. 여기에서 "@RestController"도 "@Component"도 아닌 일반 클래스 내에서이 작업을 수행하고 있음을 언급하기 위해
zulkarnain shah

1
Spring 문서에 따르면 몇 가지 문제로 인해 @Autowired를 피하는 것이 가장 좋습니다. 다음은 spring.io/understanding/application-context 링크 입니다 . 가장 좋은 방법은 ApplicationContextAware 인터페이스를 구현하는 것입니다.
Durja Arai

89

링크 는 Bean이 아닌 클래스에서도 어디서나 응용 프로그램 컨텍스트를 얻는 가장 좋은 방법을 보여줍니다. 나는 그것이 매우 유용하다고 생각합니다. 당신도 똑같기를 바랍니다. 아래는 그것의 추상적 인 코드입니다

새 클래스 ApplicationContextProvider.java 만들기

package com.java2novice.spring;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class ApplicationContextProvider implements ApplicationContextAware{

    private static ApplicationContext context;

    public static ApplicationContext getApplicationContext() {
        return context;
    }

    @Override
    public void setApplicationContext(ApplicationContext ac)
            throws BeansException {
        context = ac;
    }
}

application-context.xml에 항목 추가

<bean id="applicationContextProvider"
                        class="com.java2novice.spring.ApplicationContextProvider"/>

어노테이션의 경우 (application-context.xml 대신)

@Component
public class ApplicationContextProvider implements ApplicationContextAware{
...
}

이와 같은 맥락을 얻으십시오.

TestBean tb = ApplicationContextProvider.getApplicationContext().getBean("testBean", TestBean.class);

건배!!


1
나는 Vivek와 비슷하게 코딩했습니다. 하지만 컨텍스트에서 getBean ()을 호출해야 할 때마다 새 ApplicationContextProvider ()를 생성하지 않습니다. 내가 한 일은 정적 ApplicationContextProvider.getApplicationContext() 방법 을 갖는 것이 었습니다 . 그런 다음 현재 앱 컨텍스트가 필요할 때 다음을 호출합니다.ApplicationContextProvider appContext = ApplicationContextProvider.getApplicationContext()
Panini Luncher 2015 년

1
네 Panini Luncher, 그래도 좋을 것입니다. 귀하의 제안에 따라 그렇게 변경하겠습니다. :)
Vivek

4
애드온 @ComponentApplicationContextProvider구성을 피할 수 있습니다aplication-context.xml
bluearrow

1
참고 : 컨텍스트의 getter 및 setter는 동기화되어야합니다. 특히 단위 / 통합 테스트의 경우 많은 골칫거리를 피할 수 있습니다. 제 경우에는 유사한 ApplicationContextProvider가 많은 까다로운 버그를 일으킨 이전 컨텍스트 (이전 통합 테스트에서)를 보유했습니다.
Oleksandr_DJ

43

Spring에 의해 인스턴스화되지 않은 HttpServlet 내에서 컨텍스트에 액세스해야하는 경우 (따라서 @Autowire도 ApplicationContextAware도 작동하지 않습니다) ...

WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());

또는

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

다른 응답 중 일부 는 이렇게하기 전에 두 번 생각하십시오.

new ClassPathXmlApplicationContext("..."); // are you sure?

... 이것은 현재 컨텍스트를 제공하지 않고 대신 다른 인스턴스를 생성합니다. 이는 1) 상당한 양의 메모리와 2) 빈이이 두 애플리케이션 컨텍스트간에 공유되지 않음을 의미합니다.


SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext (this)-Liferay 포틀릿 액션 필터의 init () 메소드에서 나를 위해 일했습니다.
Igor Baiborodine 16. 04. 06.

훌륭합니다. processInjectionBasedOnCurrentContext가 필요한 모든 작업을 수행했습니다. 많은 감사 @Jaroslav
이 ì B.

ApplicationContextAware는 Vivek의 솔루션에서와 같이 @Component로 주석을 달 때 나를 위해 작동합니다 (나는 AbstractContextLoaderInitializer / createRootApplicationContext를 확장하여 수동으로 Spring 컨텍스트를 초기화하고 있습니다)
hello_earth

경고 ... SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext (this); 즉시 발생하지 않으므로 예를 들어 생성자의 첫 번째 줄로 사용할 수 없습니다.
SledgeHammer

31

JsonDeserializer와 같이 Spring에 의해 인스턴스화되지 않은 클래스를 구현하는 경우 다음을 사용할 수 있습니다.

WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
MyClass myBean = context.getBean(MyClass.class);

8
나에게는 작동하지 않습니다. 내 수업은 Spring 컨텍스트에서 벗어났습니다. 귀하의 코드를 사용하려고 시도했지만 응답 으로 null 을 제공합니다 . 내가 말하는거야ContextLoader.getCurrentWebApplicationContext()
R. Karlus

9

이것을 코드에 추가하십시오.

@Autowired
private ApplicationContext _applicationContext;

//Add below line in your calling method
MyClass class = (MyClass) _applicationContext.getBean("myClass");

// Or you can simply use this, put the below code in your controller data member declaration part.
@Autowired
private MyClass myClass;

이것은 단순히 myClass를 응용 프로그램에 삽입합니다.


6

Vivek의 답변을 기반으로하지만 다음이 더 나을 것이라고 생각합니다.

@Component("applicationContextProvider")
public class ApplicationContextProvider implements ApplicationContextAware {

    private static class AplicationContextHolder{

        private static final InnerContextResource CONTEXT_PROV = new InnerContextResource();

        private AplicationContextHolder() {
            super();
        }
    }

    private static final class InnerContextResource {

        private ApplicationContext context;

        private InnerContextResource(){
            super();
        }

        private void setContext(ApplicationContext context){
            this.context = context;
        }
    }

    public static ApplicationContext getApplicationContext() {
        return AplicationContextHolder.CONTEXT_PROV.context;
    }

    @Override
    public void setApplicationContext(ApplicationContext ac) {
        AplicationContextHolder.CONTEXT_PROV.setContext(ac);
    }
}

인스턴스 메서드에서 정적 필드로 쓰는 것은 나쁜 습관이며 여러 인스턴스가 조작되는 경우 위험합니다.


org.springframework.core.io.ContextResource인터페이스 가 있습니다. 나는 ContextResource혼란을 피하기 위해 내부 클래스에 대해 다른 이름을 선택하는 것이 좋습니다 .
Alexander Radchenko

@AlexanderRadchenko 좋아, 나는 그것을 InnerContextResource로 변경했다
Juan

1

Spring 애플리케이션에서 애플리케이션 컨텍스트를 얻는 방법은 여러 가지가 있습니다. 다음은 다음과 같습니다.

  1. ApplicationContextAware를 통해 :

    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    public class AppContextProvider implements ApplicationContextAware {
    
    private ApplicationContext applicationContext;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    }

여기 setApplicationContext(ApplicationContext applicationContext)에서 applicationContext를 얻을 수 있습니다.

  1. Autowired를 통해 :

    @Autowired
    private ApplicationContext applicationContext;

여기 @Autowired 키워드는 applicationContext를 제공합니다.

자세한 내용은 이 스레드를 방문하십시오.

감사 :)


0

또 다른 방법은 서블릿을 통해 applicationContext를 주입하는 것입니다.

이것은 Spring 웹 서비스를 사용할 때 종속성을 주입하는 방법의 예입니다.

<servlet>
        <servlet-name>my-soap-ws</servlet-name>
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
        <init-param>
            <param-name>transformWsdlLocations</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:my-applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>5</load-on-startup>

</servlet>

다른 방법은 아래와 같이 web.xml에 애플리케이션 컨텍스트를 추가하는 것입니다.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/classes/my-another-applicationContext.xml
        classpath:my-second-context.xml
    </param-value>
</context-param>

기본적으로 서블릿에게 이러한 컨텍스트 파일에 정의 된 빈을 찾아야한다고 알려 주려고합니다.


0

1 단계 : 수업에 다음 코드 삽입

@Autowired
private ApplicationContext _applicationContext;

2 단계 : Getter 및 Setter 작성

3 단계 : 빈이 정의 된 xml 파일에 autowire = "byType"정의


0

@Autowire를 추가 한 후에도 클래스가 RestController 또는 구성 클래스가 아닌 경우 applicationContext 개체가 null로 제공되었습니다. 아래에서 새 클래스 만들기를 시도했으며 제대로 작동합니다.

@Component
public class SpringContext implements ApplicationContextAware{

   private static ApplicationContext applicationContext;

   @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws 
     BeansException {
    this.applicationContext=applicationContext;
   }
 }

그런 다음 다음과 같이 Implemented 클래스 참조를 가져 오는 것과 같이 필요에 따라 동일한 클래스에서 getter 메서드를 구현할 수 있습니다.

    applicationContext.getBean(String serviceName,Interface.Class)

-11
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-servlet.xml");

그런 다음 Bean을 검색 할 수 있습니다.

MyClass myClass = (MyClass) context.getBean("myClass");

참조 : springbyexample.org


25
이 답변은 현재 컨텍스트를 제공하는 것이 아니라 다른 인스턴스를 생성합니다.
Jaroslav Záruba
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.