2009-02-12 4 views
0

У меня есть синглтон определение компонента, как это:Null Внутренняя Фасоль с Spring IoC

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

где ExampleBean может быть:

public class ExampleBean { 
    private ExampleBean2 exampleBean2; 

    public ExampleBean() { } 

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

Проблема заключается в том, что в определенных условиях com.examples.ExampleBean2class мощь не существует во время выполнения, приведет к ошибке, когда IoC пытается создать экземпляр exampleBean.

Мне нужно проигнорировать эту ошибку от IoC и разрешить создание exampleBean, но оставляя exampleBean2 объект null.

Вопрос в следующем: возможно ли это в любом случае?

Благодарим за помощь.

+0

ли ком.Примеры. ПримерBean2 singleton? – kgiannakakis

+0

На самом деле оба ExampleBean и ExampleBean2 являются одноэлементными, потому что я думаю, что это область Spring IoC по умолчанию –

ответ

1

Можно ли объявить init-метод на вашем примере, и в этом методе инициализации проверить, существует ли класс ExampleBean2, и если он его устанавливает?

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

Может быть, лучший способ делать вещи, здесь было бы использовать некоторую форму NullPattern, где вы всегда обеспечить реализацию ExampleBean2, даже если это только его «нулевое» значение.

+0

eljenso, я посмотрю на init-метод. У меня уже есть обходное решение для этого, и это похоже на описанный вами NullPattern. Благодарю. +1 –

0

возможно lazy-init будет делать это, но я думаю, что весна будет, по крайней мере проверить, если компонент реализация доступно при создании контекста приложения

+0

Michael, lazy-init не решает проблему, потому что, когда экземпляр exampleBean создается, все его зависимости также создаются (ленивы или нет), и это включает примерBean2 –

1

Если я правильно ExampleBean2 не загружен, когда Spring пытается создать экземпляр бобы. Это верно? В этом случае я не уверен, что вы могли бы многое сделать с помощью встроенных возможностей Spring.

Возможно, вы можете создать контейнерный класс, который всегда будет присутствовать. Этот класс проверяет, загружен ли ExampleBean2, и, если да, он будет создавать экземпляр экземпляра. Класс контейнера будет иметь свойство Object, которое может быть либо null, либо экземпляром ExampleBean2.

+0

kgiannakakis, ExampleBean2 загружается при создании экземпляра ExampleBean. Я все еще хочу создать экземпляр ExampleBean, даже если ExampleBean2 терпит неудачу, потому что класс не существует. У меня уже есть обходное решение для этого, и это похоже на то, что вы описали. Благодарю. +1 –

0

Возможно, это будет работать:

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; 
    } 

} 

А потом ...

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()); 
      } 
     } 
    } 

} 

А потом ...

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

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

EDIT: К сожалению о том, что, по-видимому что это не уловило внутренние бобы. Я пропустил эту деталь, когда я ее протестировал. Он захватывает только компоненты верхнего уровня. Кстати, com.examples.ExampleBean, вероятно, не будет загружаться, потому что сам он напрямую зависит от класса ExampleBean2, который виртуальная машина не найдет, вызывая ошибку

3

Если вы используете autowire, то, что вы хотите достигать возможен.

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

Или с помощью аннотаций

@Autowired(required=false) 
ExampleBean2 exampleBean2;