2012-02-02 59 views
4

我們有一個包含多個組件(小部件)的主頁,有點像包含portlet的門戶。其中一些小部件將從其他團隊的廣告瓶中提供,其中一些小部件將需要一些自定義bean由Spring進行管理。一種解決方案可能是使用帶有I通配符的import語句導入spring上下文(例如,導入類路徑中匹配context-widget - *。xml的所有上下文)。Spring在運行時添加外部彈簧上下文

但是,我更喜歡一個更加程序化的解決方案,在這裏我檢查每個小部件需要加載的上下文(來自classpath)。我沒有找到任何博客或類似的東西來解釋這一點,但是在論壇上找到了一些解釋說這是父 - 子上下文的帖子,這隻會是單向的;不幸的是在我的情況下,它需要是雙向的。

因此,在API中進行了一些瀏覽之後,我設法找到了一些可行的工作,但我不確定這是一個很好的解決方案,或者它有任何我沒有想到的陷阱。也許這種情況下有另一種(更好的)解決方案?

public class WidgetManager implements ApplicationContextAware 
{ 

    @Autowired 
    private WidgetService widgetService; 

    @Override 
    public void setApplicationContext(ApplicationContext parentApplicationContext) throws BeansException { 
     //I do need the parent context to have finished initializing beans 
     List<WidgetTO> widgets = widgetService.findAllWidgets(); 

     List<String> contexts = newArrayListWithCapacity(widgets.size()); 
     for (WidgetTO widget : widgets) { 
      if (isNotBlank(widget.getSpringContext())) { 
       contexts.add(widget.getSpringContext()); 
      } 
     } 

     AbstractRefreshableWebApplicationContext parentContext = (AbstractRefreshableWebApplicationContext) parentApplicationContext; 

     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(contexts.toArray(new String[] {}), parentApplicationContext); 
     String[] singletonNames = context.getBeanFactory().getSingletonNames(); 
     for (String s : singletonNames) { 
      //copy all singletons that don't already exist from child to parent 
      if (!parentContext.getBeanFactory().containsSingleton(s)) { 
       parentContext.getBeanFactory().registerSingleton(s, context.getBeanFactory().getSingleton(s)); 
      } 
     } 

    } 
} 
+0

你沒有提到你爲什麼需要在父上下文中可訪問的那些bean。也許它不必是雙向的?它可能會導致衝突和其他不可預知的結果。 – mrembisz 2012-02-02 12:38:16

+0

好點,它實際上是一個檢票應用程序(應該提到這一點)。主頁是wicket WebPage,Wicket Panel(通過反射初始化)的小部件。在創建窗口小部件面板時,Wicket(@SpringBean)會查找bean(在子上下文xml中定義)。我猜wicket會在父上下文中查找這個bean(是否知道任何子上下文)?至少,當我簡單地創建一個引用父上下文的新ClasspathAppcontext時,找不到該bean(除非我在父上下文xml中定義它)。 – 2012-02-02 12:57:38

+0

我看到了,不幸的是我對wicket不熟悉,但我會深入研究@SpringBean(SpringComponentInjector?)背後的機制。也許你可以自定義/替換它,並實現一個可以掃描所有兒童上下文的擴展查找。我會認真考慮使用顯式查找順序的這種算法 - 如果bean名稱重疊,該怎麼辦? - 作爲一個全球性空間,將有些不確定的父親情境。 – mrembisz 2012-02-02 13:22:16

回答

1

這實際上是我如何做到的。我們一直使用這種方式已有3年多,從未遇到過問題。

0

您可能可以使用AutowireCapableBeanFactory。這個類允許你將bean添加到現有的Spring上下文中。它將實例化bean並注入它們的依賴關係。

http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/config/AutowireCapableBeanFactory.html

我不知道我理解你說的是「雙向」的上下文的東西。你需要你的主要上下文bean來依賴於來自「子」/附加上下文的bean嗎?如果是這樣,通配符導入可能是您最好的選擇,即使您不喜歡該解決方案。

如果您更詳細地解釋整個應用程序生命週期,描述「父」/主上下文和「子」/其他上下文的階段,可能會有所幫助。

相關問題