Java 带有Spring IoC的空内部Bean

Java 带有Spring IoC的空内部Bean,java,spring,dependency-injection,inversion-of-control,Java,Spring,Dependency Injection,Inversion Of Control,我有这样一个单例bean定义: <bean id="exampleBean" class="com.examples.ExampleBean"> <property name="exampleBean2"> <bean class="com.examples.ExampleBean2" /> </property> </bean> 问题是,在某些情况下,com.examples.ExampleBean2类在运行时可能不

我有这样一个单例bean定义:

<bean id="exampleBean" class="com.examples.ExampleBean">
  <property name="exampleBean2">
    <bean class="com.examples.ExampleBean2" />
  </property>
</bean>
问题是,在某些情况下,
com.examples.ExampleBean2
在运行时可能不存在,当IoC尝试实例化
exampleBean
时,它将导致错误

我需要的是忽略IoC的这个错误,允许创建
exampleBean
,但保留
exampleBean2
属性
null

所以问题是:这有可能吗


感谢您的帮助。

在ExampleBean上声明init方法是一个选项吗?在这个init方法中,检查ExampleBean2类是否存在,如果存在,设置它

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


也许在这里更好的方法是使用某种形式的NullPattern,在这里您总是提供ExampleBean2的实现,即使它只是它的“null”值。

在ExampleBean上声明init方法是一个选项,在这个init方法中检查ExampleBean2类是否存在,如果存在,是否设置它

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


也许在这里更好的方法是使用某种形式的NullPattern,您总是提供ExampleBean2的实现,即使它只是它的“null”值。

也许会这样做,但我认为spring至少会在创建应用程序上下文时检查bean实现类是否可用,但我认为spring至少会在创建应用程序上下文时检查bean实现类是否可用,如果我做对了,例如spring尝试实例化bean时没有加载Bean2。这是正确的吗?在这种情况下,我不认为你可以用Spring的内置功能做很多事情


也许您可以创建一个始终存在的容器类。这个类将检查ExampleBean2是否被加载,如果是,它将实例化它的一个实例。容器类将有一个对象属性,该属性可以是null,也可以是ExampleBean2的实例。

如果我做对了,当Spring尝试实例化bean时,ExampleBean2没有加载。这是正确的吗?在这种情况下,我不认为你可以用Spring的内置功能做很多事情


也许您可以创建一个始终存在的容器类。这个类将检查ExampleBean2是否被加载,如果是,它将实例化它的一个实例。容器类将有一个对象属性,该属性可以是null,也可以是ExampleBean2的实例。

也许这样可以:

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>


编辑:很抱歉,这似乎没有捕获内部bean。我在测试时忽略了这个细节。它只捕捉顶级豆子。顺便说一句,com.examples.ExampleBean可能无论如何都不会加载,因为它本身直接依赖于ExampleBean2类,而虚拟机找不到该类,从而导致错误

也许这样可以:

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>


编辑:很抱歉,这似乎没有捕获内部bean。我在测试时忽略了这个细节。它只捕捉顶级豆子。顺便说一句,com.examples.ExampleBean可能无论如何都不会加载,因为它本身直接依赖于ExampleBean2类,而虚拟机找不到该类,这会导致错误

如果使用autowire,您希望实现的目标是可能的

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

如果您使用autowire,您希望实现的目标是可能的

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

com.examples.ExampleBean2是单例吗?实际上ExampleBean和ExampleBean2都是单例bean,因为我认为它是Spring IoC默认范围是com.examples.ExampleBean2是单例吗?实际上ExampleBean和ExampleBean2都是单例bean,因为我认为它是Spring IoC默认范围Michael,lazy init不会解决它,因为当实例化exampleBean时,它的所有依赖项也会实例化(懒惰与否),这包括ExampleBean2 Michael,lazy init不会解决它,因为当实例化exampleBean时,它的所有依赖项也会实例化(懒惰与否),这包括ExampleBean2kgiannakis,实例化ExampleBean时加载ExampleBean2。我仍然希望实例化ExampleBean,即使ExampleBean2失败,因为该类不存在。我已经有了一个类似于您描述的解决方法。谢谢+1kgiannakakis,ExampleBean2在实例化ExampleBean时加载。我仍然希望实例化ExampleBean,即使ExampleBean2失败,因为该类不存在。我已经有了一个类似于您描述的解决方法。谢谢+1eljenso,我来看看init方法。我已经有了一个类似于您描述的NullPattern的解决方法。谢谢+1eljenso,我来看看init方法。我已经有了一个类似于您描述的NullPattern的解决方法。谢谢+1.