3

ApplicationContext を Spring Container として使用しています。

ただし、API を変更したくないため、次のようにコンテナーの複数のインスタンスを使用する必要があると感じています。

public static void main(String[] args)
 { 
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

    ...
    objA = context.getBean(...);
    objB = context.getBean(...);
 }

// code for Class A

 public void execute() // <-- cannot change this signature 
 {
     ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
     objC = context.getBean(...); // earlier, this was objC = new C();
     objC.method1("...");
 }

したがって、ApplicationContext の 2 つの異なるインスタンスを使用することになります。ApplicationContext の複数のインスタンスを持つことが適切な場合と適切でない場合はいつですか?

4

6 に答える 6

2

ほとんどのアプリケーションでは、複数の ApplicationContext は必要ありません。主な制限は、コンテナー間で Bean インスタンスを共有できないことです。技術的には、それらを 2 つのコンテナーに分割できない理由はありませんが、データソースや共通のビジネス レイヤーなど、共有したい共通の Bean がいくつかあると確信しています。

あなたの例を見ると、クラス A が SpringApplication コンテキストをコンストラクターとして受け入れることを許可することをお勧めします (または、セッターメソッドを使用することもできます)

public class A {

    private ApplicationContext ctx;

    public A(ApplicationContext applicationContext) {   
        ctx = applicationContext;
    }

    public void execute() {
        // do stuff with beans retrieved from "ctx"
    }
}

main() はブートストラップします。コンテキストを取得し、それをのインスタンスに渡しますA

public class MyMain {

    public static void main(String[] args) {

        A a = new A(SpringContextFactory.getInstance());

        a.execute();        
    }
}

優れた設計の追加部分として、作成したコンテキストを Factory クラス内にカプセル化します

public class SpringContextFactory {

    public static ApplicationContext getInstance() {

        String[] contextXml = new String[]{ "resources/spring-context.xml",
                                            "resources/spring-db.xml" };

        return new ClassPathXmlApplicationContext(contextXml);
    }
}

このセットアップは単体テストでうまく機能することがわかりました

于 2012-06-12T16:21:57.667 に答える
1

クラスを制御できる場合は、ApplicationContextAwareを実装してみてください: http ://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/ApplicationContextAware.html

これにより、applicationContextがクラスに挿入され、必要なクラスを取得する自由が与えられます。

Aクラスが春までに初期化される限り、これは機能します。与えられたコードから、これが当てはまります。

于 2012-06-12T18:33:19.887 に答える
1

私のテストでは、ユーティリティ クラスを作成し、単純に静的インスタンスを使用してシングルトンを作成しました。

例えば:

 public class Utilities {
private static ApplicationContext _applicationContext = null; 
private static void initApplicationContext() {
        if (_applicationContext == null) {
            _applicationContext = 
new ClassPathXmlApplicationContext("PersistenceHelper-context.xml");
        }
    }
}

その後、必要なときにいつでも次のように言ってください。

Utilities.initApplicationContext();
于 2012-06-12T18:13:33.527 に答える
0

複数のアプリケーション コンテキストを持つ必要はありません。多くの場合、共有アプリケーション コンテキストが必要です。

アプリケーションで複数のアプリケーション コンテキストを作成しないようにするには、次の手順を実行します。

applicationcontextprovider Bean が作成されると、Spring フレームワークは ApplicationContext を setApplicationContext に注入します。

これで、必要に応じてアプリケーション コンテキストを返す静的ユーティリティ メソッド getApplicationContext が 1 つあります。

アプリケーションコンテキストが必要なときはいつでも、次のように言うだけです:ApplicationContextProvider.getApplicationContext(); 、共有アプリケーション コンテキストを返します。

/* アプリケーション コンテキスト プロバイダー クラス */

public class ApplicationContextProvider implements ApplicationContextAware {

    private static Logger logger = Logger.getLogger(ApplicationContextProvider.class);

    private static ApplicationContext ctx;

    @Override
    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        if (arg0 != null) {
            ctx=arg0;
        }
    }

    public synchronized static ApplicationContext getApplicationContext(){
        if (ctx==null) {
            logger.info("Getting the context again as it is null");
            ctx = new ClassPathXmlApplicationContext("Spring-All-Module.xml");
        }
        return ctx;
    }


}

春の XML:

<bean id="applicationContextProvider" class="dell.harmony.service.ApplicationContextProvider"></bean> 

メイン プログラム クラスから:

try {
            logger.info("Spring Application Context !!");
            ApplicationContext context = new ClassPathXmlApplicationContext(
                    "/Spring-All-Module.xml");
            logger.info("Spring Application Context - End !!");
        } catch (Exception e) {
                    logger.error("Exception in getting the Spring Application Context !!");
                     /* log the exception */
        }

コンテキストが必要なときはいつでも、次のように言うだけです: //get application context

ApplicationContext コンテキスト = ApplicationContextProvider.getApplicationContext();
dl = (SingleDataLoader) context.getBean("singledataloaderdao");

于 2013-10-18T08:49:29.660 に答える
0

現在のコードでは、Spring を正しく使用していません。アイデアは、Spring で依存関係を結び付けてから、それを使用ApplicationContextして開始 Bean を (おそらくmain()メソッドから) ロードすることです。異なる Bean を取得するためだけに、複数の場所で同じコンテキストを複数回ロードすることは理想的ではありません。

私が知る限り、コードは(または)のインスタンスをそのメンバーClassAにしようとする必要があります。はすでに Spring 定義の Bean であるため、これを実行したいと考えています。Beanに対して Spring に提供されるスコープに応じて、Bean を直接 (スコープに対して)注入する必要があります。@AutowiredClassCObjectCClassAClassCsingleton

@Autowired
private ClassC objC;

または、Bean のインスタンスを作成するためのファクトリを注入する必要があります (prototypeスコープ用)。

@Autowired
private ClassCFactory objCFactory;

この変更を行う場合、ApplicationContext複数回ロードする必要はありません。

于 2012-06-12T16:18:35.957 に答える
-1

メインメソッドであなたのプログラムのコンテキストにcontext入れてみてください。他のメソッドでは取得する必要があります。あなたの場合、いくつかのコンテキストクラスから静的メソッドを使用してください。それは良いことではありませんが、APIを変更することはできませんapplication context

于 2012-06-12T16:11:14.867 に答える