0

我对 spring 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是有两个孩子的父上下文:BC. 您定义cacheManager了两次:在 parentConfigA和一个 childConfigC中。不同的应用程序上下文可以有相同的 bean,这就是为什么你会得到两个不同的实例。

换句话说,如果您要求cacheManagerfrom ConfigC,它会返回在该上下文中定义的那个。ConfigB但是如果你从or请求它ConfigA,它会从ConfigA(其他实例)返回一个。

它们仍然是单例,但在单个应用程序上下文的范围内。顺便说一句,你能描述一下你想用这个相当复杂的架构实现什么吗?

于 2013-02-09T15:55:02.973 回答