2013-02-09 81 views
0

我在Spring AnnotationConfigApplicationContext中遇到了一些问题。春天cacheManager不是单身?

主要目标是创建可以在应用程序服务器上运行的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"); 
    } 
} 

我已经花了很多时间来解决这个问题 - 如果有人会帮助我会很高兴

回答

0

如果我理解正确A是具有两个子项的父上下文:BC。您定义两次cacheManager:父母ConfigA和一个孩子ConfigC。不同的应用程序上下文可以有相同的bean,这就是为什么你得到两个不同的实例。

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

它们仍然是单身人士,但在单个应用程序上下文的范围内。顺便说一句,你能描述一下你想用这个非常复杂的体系结构实现什么?

+0

删除后第二个cacheManager声明 – 2013-02-09 15:58:09

+0

同样的问题关于目标:我有一个模块化的解决方案。这个解决方案可以在Application Server上独立执行(因此有不同的方式来实现一些对象,例如DataSource等),但是我的公共部分包含在ConfigA中。在那之后,每个模块都有自己的配置和特定的bean。我同意这很复杂,但对我来说 - 非常合乎逻辑 – 2013-02-09 16:11:06