2012-04-03 13 views
0

Ich versuche, einen Spring BeanFactoryPostProcessor zu schreiben, der jede Bean finden kann, die eine Init-Methode definiert. Ich habe Glück bei der Suche Bohnen, die Namen, aber nicht verschachtelt namenlos Bohnen wie in dem Ziel Bohne in folgendem Beispiel hat:Kann ein Spring BeanFactoryPostProcessor verschachtelte Beans ohne Namen finden?

<bean id="aclDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager"><ref bean="transactionManager"/></property> 
    <property name="target"> 
     <bean class="com.vidsys.dao.impl.acl.ACLDaoImpl" init-method="init"> 
      <property name="sessionFactory"><ref local="sessionFactory"/></property> 
     </bean> 
    </property> 
    <property name="transactionAttributes"> 
    <props> 
    <prop key="*">PROPAGATION_REQUIRED</prop> 
    </props> 
    </property> 
</bean> 

Als ich die Bohnen in meinem BeanFactoryPostProcessor Liste nur scheine ich die, die mit Namen zu erhalten, wie in mit dem folgenden Code:

public class BeanInitializationFinder implements BeanFactoryPostProcessor, Ordered { 
    @Override 
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 
    throws BeansException { 

     //String[] beanDefs = BeanFactoryUtils.beanNamesIncludingAncestors(beanFactory); 
     String[] beanDefs = beanFactory.getBeanDefinitionNames(); 
     for(String defName : beanDefs) { 
      BeanDefinition def = beanFactory.getBeanDefinition(defName); 
      if(null == def.getBeanClassName() || !(def instanceof AbstractBeanDefinition)) 
       return; 
      } 
      AbstractBeanDefinition abd = (AbstractBeanDefinition) def; 
      try { 
       if(abd.getFactoryMethodName() == null && abd.getFactoryBeanName() == null) 
        Class<?> beanClass = Class.forName(abd.getBeanClassName()); 
        if(InitializingBean.class.isAssignableFrom(beanClass) || null != abd.getInitMethodName()) { 
         beansWithInits.add(defName); 
        } 
       } 
      } 
      catch(Exception e) { 
       throw new BeanIntrospectionException("Failed to instrospect bean defs", e); 
      } 
     } 
    } 

} 

Ich mag würde die ganze Bohne erhalten, die eine init-Methode, einschließlich verschachtelt Bohnen, die namenlos sind. Kann ich das machen?

Antwort

1

Sie können verschachtelte BeanDefinitions abrufen, jedoch nicht über beanFactory.getBeanDefinition. Die einzige Möglichkeit, zu verschachtelten Bean-Definitionen zu gelangen, ist die PropertyValues des übergeordneten Elements BeanDefinition - Sie müssen das Diagramm durchlaufen.

Beispielsweise (und fehlt jedes Null-checking):

BeanDefinition parentDef = beanFactory.getBeanDefinition(defName); 
for (PropertyValue property : parentDef.getPropertyValues().getPropertyValues()) { 
    Object value = property.getValue(); 
    if (value instanceof BeanDefinitionHolder) { 
     BeanDefinition nestedDef = ((BeanDefinitionHolder)value).getBeanDefinition(); 
    } 
} 

Da Graph Traversal gut mit den Besucher-Mustern funktioniert, können Sie org.springframework.beans.factory.config.BeanDefinitionVisitor Unterklasse dieses in einer prägnanten Art und Weise zu tun.

Verwandte Themen