2009-02-12 6 views
0

J'ai une définition de haricot singleton comme ceci:Null Bean intérieur avec Spring IoC

<bean id="exampleBean" class="com.examples.ExampleBean"> 
    <property name="exampleBean2"> 
    <bean class="com.examples.ExampleBean2" /> 
    </property> 
</bean> 

ExampleBean pourrait être:

public class ExampleBean { 
    private ExampleBean2 exampleBean2; 

    public ExampleBean() { } 

    public ExampleBean2 getExampleBean2() { return exampleBean2; } 
    public void setExampleBean2(ExampleBean2 exampleBean2) { this.exampleBean2 = exampleBean2; } 
} 

Le problème est que, dans certaines conditions, la com.examples.ExampleBean2class pourrait n'existe pas au moment de l'exécution, provoquera une erreur lorsque l'IoC essayera d'instancier exampleBean. Ce dont j'ai besoin est d'ignorer cette erreur de l'IoC et de permettre la création du exampleBean mais de la propriété exampleBean2null.

La question est donc: est-ce possible en aucune façon?

Merci pour votre aide.

+0

est-com.examples.ExampleBean2 le singleton? – kgiannakakis

+0

En fait les deux ExampleBean et ExampleBean2 sont des beans singleton parce que je pense que c'est la portée par défaut de Spring IoC –

Répondre

1

Est-ce une option pour déclarer une méthode init sur votre ExampleBean, et dans cette init-method vérifier si la classe ExampleBean2 existe, et si c'est le cas?

<bean id="exampleBean" class="com.examples.ExampleBean" init-method="init"/> 

Peut-être une meilleure façon de faire les choses ici serait d'utiliser une certaine forme de la NullPattern, où vous toujours fournir une implémentation de ExampleBean2, même si elle est seulement sa valeur « nulle ».

+0

eljenso, je vais jeter un oeil à init-method. J'ai déjà une solution de contournement pour cela et c'est similaire au NullPattern que vous avez décrit. Merci. +1 –

0

peut-être lazy-init va le faire, mais je pense que le printemps sera au moins vérifier si la classe de mise en œuvre de haricot est disponible à la création du contexte d'application

+0

Michael, lazy-init ne le résout pas car lorsque exampleBean est instancié, toutes ses dépendances sont également instanciées (paresseuses ou non) et cela inclut exampleBean2 –

1

Si je me trompe pas ExampleBean2 n'est pas chargé quand le printemps essaie d'instancier les haricots. Est-ce correct? Dans ce cas, je ne pense pas que vous pourriez faire beaucoup avec les capacités intégrées de Spring.

Peut-être que vous pourriez créer une classe de conteneur qui sera toujours présent. Cette classe vérifiera si ExampleBean2 est chargé et si oui, il instanciera une instance de celui-ci. La classe conteneur aura une propriété Object qui pourrait être soit null, soit l'instance de ExampleBean2.

+0

kgiannakakis, ExampleBean2 est chargé lorsque ExampleBean est instancié. Je veux toujours instancier ExampleBean même si ExampleBean2 échoue parce que la classe n'existe pas. J'ai déjà une solution de contournement pour cela et c'est similaire à ce que vous avez décrit. Merci. +1 –

0

Peut-être que cela fonctionnera:

public class NullFactoryBean implements FactoryBean { 

    @Override 
    public Object getObject() throws Exception { 
     return null; 
    } 

    @Override 
    public Class<?> getObjectType() { 
     return Object.class; 
    } 

    @Override 
    public boolean isSingleton() { 
     return false; 
    } 

} 

Et puis ...

public class ClassNotFoundPostProcessor implements BeanFactoryPostProcessor { 

    @Override 
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
     String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); 
     for (String beanDefinitionName : beanDefinitionNames) { 
      BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName); 
      String beanClassName = beanDefinition.getBeanClassName(); 
      try { 
       Class.forName(beanClassName); 
      } catch (ClassNotFoundException e) { 
       beanDefinition.setBeanClassName(NullFactoryBean.class.getName()); 
      } 
     } 
    } 

} 

Et puis ...

<beans> 
    <bean id="exampleBean" class="com.examples.ExampleBean"> 
     <property name="exampleBean2"> 
      <bean class="com.examples.ExampleBean2" /> 
     </property> 
    </bean> 

    <bean class="ClassNotFoundPostProcessor" /> 
</beans> 

EDIT: Je suis désolé, il semble que cela n'a pas attrapé les haricots intérieurs. J'ai manqué ce détail quand je l'ai testé. Il ne capture que les haricots de haut niveau. Par ailleurs, com.examples.ExampleBean ne se chargera probablement pas de toute façon car il dépend lui-même directement de la classe ExampleBean2, que la machine virtuelle ne trouvera pas, provoquant une erreur

3

Si vous utilisez autowire, ce que vous voulez réaliser est possible.

<bean class="com.examples.ExampleBean" autowire="byType" /> 
<bean class="com.examples.ExampleBean2" /> 

ou via des annotations

@Autowired(required=false) 
ExampleBean2 exampleBean2; 
Questions connexes