Springは現在のApplicationContextを取得します


105

Webアプリケーションに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

回答:


160

注入するだけです。

@Autowired
private ApplicationContext appContext;

または、このインターフェースを実装します:ApplicationContextAware


多分これはうまくいくかもしれません:stackoverflow.com/questions/11682858/…–
gipinani

次のApplicationContextProvider.java回答は、これに対する最も信頼できるソリューションであると思われます。
Ionut 2016年

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()
パニーニLuncher

1
はい、パニーニランチャー、それでも良いでしょう。あなたの提案に従って、私はそれをそのように変更します。:)
Vivek 2015

4
アドオン@ComponentApplicationContextProvider構成を回避できますaplication-context.xml
bluearrow

1
注:コンテキストのゲッターとセッターは同期する必要があります。特に単体テストや統合テストでは、多くの頭痛の種を避けられます。私の場合、同様のApplicationContextProviderが(以前の統合テストからの)古いコンテキストを保持しており、多くのトリッキーなバグを引き起こしていました。
Oleksandr_DJ

43

Springによってインスタンス化されていないHttpServlet内からコンテキストにアクセスする必要がある場合(したがって、@ AutowireもApplicationContextAwareも機能しません)...

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

または

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

他の返信のいくつかについては、これを行う前によく考えてください。

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

...これは現在のコンテキストを提供するのではなく、代わりに別のインスタンスを作成します。つまり、1)かなりの量のメモリと2)Beanがこれら2つのアプリケーションコンテキスト間で共有されません。


SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this)-Liferayポートレットアクションフィルタのinit()メソッドで私のために仕事をしました。
Igor Baiborodine

すごい、processInjectionBasedOnCurrentContextは私が必要とするすべての仕事をしました。本当にありがとう@Jaroslav
Jad 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.

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 OK、それを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 Webサービスの使用時に依存関係を挿入する方法の例です。

<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>

基本的に、これらのコンテキストファイルで定義されたBeanを探す必要があることをサーブレットに伝えようとしています。


0

ステップ1:クラスに次のコードを挿入する

@Autowired
private ApplicationContext _applicationContext;

ステップ2:ゲッターとセッターを書く

手順3:Beanが定義されているXMLファイルでautowire = "byType"を定義します


0

@Autowireを追加した後でも、クラスがRestControllerまたはConfiguration Classでない場合は、applicationContextオブジェクトがnullになっていました。以下で新しいクラスを作成しようとしましたが、うまくいきます:

@Component
public class SpringContext implements ApplicationContextAware{

   private static ApplicationContext applicationContext;

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

その後、次のようにしてImplementedクラス参照を取得するように、必要に応じて同じクラスにゲッターメソッドを実装できます。

    applicationContext.getBean(String serviceName,Interface.Class)

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

次に、Beanを取得できます。

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

リファレンス:springbyexample.org


25
この答えは現在のコンテキストを提供するのではなく、別のインスタンスを作成します。
JaroslavZáruba2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.