多个Spring应用程序上下文使用不同的类加载器?

时间:2012-08-22 21:42:36

标签: spring aspectj

人们通常希望让多个Web应用程序共享对单个应用程序上下文的访问权限。如何描述例如here

这个问题恰恰相反:在单个Web应用程序中有多个应用程序上下文。通常这很容易,您只需创建它们并使用它们。

然而,在Spring方面存在一些由静态变量引起的情况,例如:

  • 您有两个应用程序上下文X和Y,它们都创建一个MyBean,其@Transactional注释
  • X和Y都包含自己的事务管理器
  • X和Y都有<tx:annotation-driven mode="aspectj"/>声明
  • 您正在进行构建时间AspectJ编织

在这种情况下,问题是<tx:annotation-driven mode="aspectj"/>实际上已转换为这样的bean:

<bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect"
  factory-method="aspectOf"/>

请注意,这会返回AnnotationTransactionAspect的方面对象,它是存储在静态变量中的单例。 AnnotationTransactionAspect扩展TransactionAspectSupport,其中包含例如缓存事务管理器。

效果是即使X和Y中的bean完全分开,它们也会在AnnotationTransactionAspect方面单例中的相同实例字段上进行争夺。这导致例如“没有事务正在进行中”例外,因为有人得到了错误的事务管理器。

@Configurable也发生了同样的事情:用于配置bean的bean工厂存储在一个静态变量中(参见AnnotationBeanConfigurerAspect.beanConfigurerSupport)。这是一个更大的问题,因为您可以使用@Transactional避免使用AspectJ,但是使用@Configurable无法避免使用它。

我可以想到三个解决方案:

  1. 停止使用方面
  2. 写我自己的方面
  3. 在创建X和Y
  4. 的线程中创建/设置新的上下文类加载器

    选项#1很糟糕,因为我非常喜欢@Configurable

    选项#2看起来不太有趣。

    选项#3看起来很简单。

    那么#3选项如何运作?这是我模糊的地方。我需要将Spring类加载到X和Y中的不同类加载器中。这意味着上下文类加载器无法正常委托给它的父(Web应用程序类加载器)等。你会如何设置它? / p>

    感谢。

0 个答案:

没有答案