2011-04-11 95 views
2

,這裏是我的config.xml的BeanPostProcessor不叫

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation=" 
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 

    <context:component-scan base-package="com"> 
     <context:include-filter type="assignable" expression="com.coc.frmwk.cmd.Command"/> 
     <context:include-filter type="assignable" expression="com.coc.apps.sample.dao.SampleDAO"/> 
    </context:component-scan> 

<bean id="myPostProcessor" class="com.coc.frmwrk.processors.MyPostProcessor"> 
</beans> 

我知道,使用組件掃描時,將被分配到豆默認範圍是「單身」,除非它另有規定的xml配置或使用註釋@Scope,這很酷,但由於我已經在我的應用程序中發現了所有實現特定接口(com.coc.frmwk.cmd.Command)的bean需要將它們的作用域設置爲「prototype」,所以我添加了一個實現ScopeMetaDataResolver的類「ScopeResolver」,並且我對config.xml進行了一些修改,以便容器考慮到我的範圍解析器:

<context:component-scan base-package="com" scope-resolver="com.coc.frmwk.processors.ScopeResolver"> 

我的問題是,BeanPostProcessor用於完美工作,但是當我添加作用域解析器時,它會停止調用(context:component-scan base-package =「com」scope-resolver =「com.xxx。 frmwk.processors.ScopeResolver「),當我以粗體忽略這些東西時,它會再次運行。

關於如何在配置ScopeResolver時使BeanPostProcessor工作的任何想法? 謝謝,邁赫迪。

編輯:這是我的範圍解析器

package com.coc.frmwk.processors; 

import org.springframework.beans.factory.config.BeanDefinition; 
import org.springframework.context.annotation.ScopeMetadata; 
import org.springframework.context.annotation.ScopeMetadataResolver; 

import com.coc.frmwk.cmd.Command; 

public class ScopeResolver implements ScopeMetadataResolver{ 

    @SuppressWarnings("unchecked") 
    @Override 
    public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { 
     ScopeMetadata result = new ScopeMetadata(); 

     Class c= null; 
     try { 
      c = Class.forName(definition.getBeanClassName()); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 
     if (Command.class.isAssignableFrom(c)) 
     result.setScopeName("prototype"); 
     else 
     result.setScopeName("singleton"); 

     System.out.println("[Scope Resolver] " + definition.getBeanClassName() + "[" + result.getScopeName() + "]"); 

     return result; 
    } 

} 

EDIT2的內容:我想指出的是,當BeanPostProcessor,其實是在被稱爲,但顯然它除了那些所有的豆類工程由ScopeMeteDataResolver更改其範圍。

+0

如果比較您生成的容器和作用域中的其他bean的實際作用域,它可能有助於診斷它。 – 2011-10-25 03:13:33

回答

1

我還沒有找到如何解決問題,但我找到了解決方法,這可能對任何人有同樣的問題有用。
好,而不是使用BeanPostProcessor和MetaDataScopeResolver的組合,我決定使用BeanFactoryPostProcessor來管理範圍解析和bean處理。 here'ds當BeanFactoryPostProcessor的興趣的人的代碼:

@Component 
public class OaliaBeanFactoryPostProcessor implements BeanFactoryPostProcessor { 

    @SuppressWarnings("unchecked") 
    public void postProcessBeanFactory(
      ConfigurableListableBeanFactory beanFactory) throws BeansException { 
     for(String beanName : beanFactory.getBeanDefinitionNames()) 
     { 
      //Scope resolution 
      BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); 
      Class beanClass= null; 
      try { 
       beanClass = Class.forName(beanDefinition.getBeanClassName()); 
      } catch (ClassNotFoundException e) { 
       // exception handling goes here 
      } 
      if (Command.class.isAssignableFrom(beanClass)) 
       beanDefinition.setScope("prototype"); 

      //Stuff that the BeanPostProcessor do go here 
      //.......... 
      //.......... 

      System.out.println("[Post Processing] " + beanName + " [" + beanDefinition.getScope() + "]"); 
     } 
     } 
    } 
2

您所描述的行爲是我所期望的行爲。 (至少在啓動時),只要構建bean,就會調用BeanPostProcessor,原型scoped bean僅在請求時才構造。所以如果你不使用這個bean,BeanPostProcessor將不會被調用。

但是根據你想要的修改配方(BeanDefinition而不是創建的bean實例)來判斷。爲了檢查食譜,你需要使用BeanFactoryPostProcessor

不同之處在於BeanPostProcessor在豆實例上運行,其中BeanFactoryPostProcessor在豆創建食譜(BeanDefinitions)上工作。