0

春の AnnotationConfigApplicationContext に問題があります。

主な目的は、アプリケーション サーバーまたはスタンドアロンで実行できる Spring 構成を作成することです。このサブコンテキストから、同じ AppServer 上の別のアプリケーションで使用されるサブコンテキストを作成するサブタスク。ただし、cacheManager には問題があります。

それが私のコードです:別名AbstractConfig

package org.zib.test.a;


import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;


@Configuration
@EnableCaching
public class ConfigA {

    @SuppressWarnings("UnusedDeclaration")
    public static ApplicationContext getContext() {
        return ContextA.getInstance().getContext();
    }


/**
 * use {@link org.zib.test.b.ContextB}
 */
public static <T> T getBean(Class<T> bean) {
    return ContextB.getInstance().getContext().getBean(bean);
}
/**
 * use {@link ContextB}
 */
public static <T> T getBean(String name, Class<T> bean) {
    return ContextB.getInstance().getContext().getBean(name, bean);
}

    @Bean(name = "cacheManager")
    public CacheManager cacheManager() {
        // configure and return an implementation of Spring's CacheManager SPI
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
        return cacheManager;
     }

 }

別名AbstractContext

package org.zib.test.a;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ContextA {
    private ApplicationContext applicationContext;

    public static ContextA instance;

    public static ContextA getInstance() {
        synchronized (ContextA.class) {
            if (instance == null)
                instance = new ContextA();
        }
        return instance;
    }

    private ContextA() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(ConfigA.class);
        applicationContext.registerShutdownHook();
        applicationContext.refresh();
        this.applicationContext = applicationContext;
    }

    public ApplicationContext getContext() {
        return applicationContext;
    }
}

モード構成 (WebLogicConfig など)

package org.zib.test.b;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.zib.test.a.ConfigA;


@Configuration
@EnableCaching
@Import(ConfigA.class)
public class ConfigB {

    @SuppressWarnings("UnusedDeclaration")
    public static ApplicationContext getContext() {
        return ContextB.getInstance().getContext();
    }
    /**
     * use {@link ContextB}
     */
    public static <T> T getBean(Class<T> bean) {
        return ContextB.getInstance().getContext().getBean(bean);
    }
    /**
     * use {@link ContextB}
     */
    public static <T> T getBean(String name, Class<T> bean) {
        return ContextB.getInstance().getContext().getBean(name, bean);
    }
}

環境:

package org.zib.test.b;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.zib.test.a.ContextA;

public class ContextB {
    private ApplicationContext applicationContext;

    public static ContextB instance;

    public static ContextB getInstance() {
        synchronized (ContextB.class) {
            if (instance == null)
                instance = new ContextB();
        }
        return instance;
    }

    private ContextB() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(ConfigB.class);
        applicationContext.setParent(ContextA.getInstance().getContext());
        applicationContext.registerShutdownHook();
        applicationContext.refresh();
        this.applicationContext = applicationContext;
    }

    public ApplicationContext getContext() {
        return applicationContext;
    }
}

最後に - モジュール構成:

package org.zib.test.c;


import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;


@Configuration
@EnableCaching
public class ConfigC {

    @SuppressWarnings("UnusedDeclaration")
    public static ApplicationContext getContext() {
        return ContextC.getInstance().getContext();
    }
    /**
     * use {@link ContextC}
     */
    public static <T> T getBean(Class<T> bean) {
        return ContextC.getInstance().getContext().getBean(bean);
    }

    /*DELTE BY SUGGESTION OF Tomasz Nurkiewicz
    @Bean(name = "cacheManager")
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
        return cacheManager;
    }*/
}

およびそのコンテキスト:

package org.zib.test.c;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.zib.test.a.ContextA;
import org.zib.test.b.ContextB;

public class ContextC {
    private ApplicationContext applicationContext;

    public static ContextC instance;

    public static ContextC getInstance() {
        synchronized (ContextC.class) {
            if (instance == null)
                instance = new ContextC();
        }
        return instance;
    }

    private ContextC() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(ConfigC.class);
        applicationContext.setParent(ContextA.getInstance().getContext());
        applicationContext.registerShutdownHook();
        applicationContext.refresh();
        this.applicationContext = applicationContext;
    }

    public ApplicationContext getContext() {
        return applicationContext;
    }
}

私のテストクラス:

package org.zib.test;

import org.springframework.cache.CacheManager;
import org.zib.test.a.ConfigA;
import org.zib.test.c.ConfigC;

public class Test {
    public static void main(String[] args) {
        Object cm1 = ConfigC.getBean(CacheManager.class);
        Object cm2 = ConfigA.getBean(CacheManager.class);

        if (cm1 == cm2)
            System.out.println("equals");
        else
            System.out.println("unequal");
    }
}

私はすでにこの問題を解決するために多くの時間を費やしてきました - 誰かが私を助けてくれれば幸いです

4

1 に答える 1

0

私が正しく理解していれば、とAの 2 つの子を持つ親コンテキストです。親と 1 つの子の2 回定義します。異なるアプリケーション コンテキストが同じ Bean を持つことができるため、2 つの異なるインスタンスが取得されます。BCcacheManagerConfigAConfigC

つまり、cacheManagerfromを要求するConfigCと、そのコンテキストで定義されたものを返します。ただし、ConfigBまたはから要求すると、 (他のインスタンス)ConfigAからのものが返されます。ConfigA

それらはまだシングルトンですが、単一のアプリケーション コンテキストの範囲内にあります。ところで、この非常に複雑なアーキテクチャで達成したいことを説明できますか?

于 2013-02-09T15:55:02.973 に答える