Spring xml ioc对Java实例化有什么好处?

时间:2013-01-08 16:39:44

标签: java xml spring inversion-of-control

好的,这个问题会得到很多挫折......

我刚刚看到this question,其中一个人面临一些关于spring xml beanfactory问题的问题。

我想理解为什么:

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="namingStrategy">
        <ref bean="namingStrategy"/>
    </property>
    <property name="mappingResources">
        <list>
            <!--<value>genericdaotest/domain/Person.hbm.xml</value>-->
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
        </props>
    </property>
    <property name="dataSource">
        <ref bean="dataSource"/>
    </property>
</bean>

无论如何应该比这更好:

public class BeanFactory {
    public LocalSessionFactoryBean getSessionFactory() {
        LocalSessionFactoryBean bean = new LocalSessionFactoryBean();
        bean.setNamingStrategy(getNamingStrategy());
        bean.setMappingResources(Arrays.asList(getPerson());
        bean.setHibernateProperties(new Properties() {{ 
           setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
           setProperty("hibernate.show_sql", "true")
           setProperty("hibernate.hbm2ddl.auto", "create");
        }});
        bean.setDataSource(getDataSource());
        return bean;
    }
}

它更短,更容易理解,它没有Spring怪癖,它不需要运行外部库(可能与其他人发生冲突),它是逐步可调试的,它可以单元测试,它不需要反射,它可能有利于OOP,它更容易从IDE重构,它在编译时检查类型,它是Java-not xml-并且不需要在运行时解析,当它编译时你知道已经正式正确(并且没有在运行时发现异常),如果你需要外化一些配置参数,你可以使用属性文件(包含真实配置)。

而不仅仅是一切:我不需要在我的代码中使用一个名为“BeanFactory”的庞大单例类,他的职责是实例化各种对象(就像一个与IoC原则无关的庞大而丑陋的服务定位器)

所以,问题是:

  

为什么我更喜欢创建一个巨大的XML而不是创建我的对象,用Java编写和聚合它们?

6 个答案:

答案 0 :(得分:5)

使用相对现代版本的Spring,您根本不会被迫使用xml。只需按如下方式注释您的课程......

@Configuration
public class BeanFactory {
     @Bean
     public LocalSessionFactoryBean sessionFactory() {
         LocalSessionFactoryBean bean = new LocalSessionFactoryBean();
        bean.setNamingStrategy(getNamingStrategy());
        bean.setMappingResources(Arrays.asList(getPerson());
        bean.setHibernateProperties(new Properties() {{ 
           setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
           setProperty("hibernate.show_sql", "true")
           setProperty("hibernate.hbm2ddl.auto", "create");
        }});
        bean.setDataSource(dataSource());
        return bean;
    }

    @Bean
    public DataSource dataSource() { 
    ....
}

依赖注入的真正好处在于使用bean的类。您的代码不会出现管道代码,它专注于解决业务问题。

答案 1 :(得分:1)

更好的问题可能是“依赖注入有哪些优势?”毕竟,还有其他依赖注入框架,它们使用纯java而不是XML。 (见Google Guice

这一切都归结为找到有用的技术来解耦你的代码,然后将它们“连接”在其他地方。

答案 2 :(得分:1)

  

为什么我更喜欢创建一个巨大的XML而不是创建我的对象,用Java编写和聚合它们?

我对收到的答案的理解是,许多人认为XML不是源代码,而是配置。因此,修改XML被认为比更改Java类风险更小或更方便。

通过修改Java源修改XML的好处是您不需要重新编译应用程序;因此,在测试/生产中可以更轻松地推动这些更改,而无需参与正常的开发活动(和测试)。 而这 - 在我个人看来 - 是故事中最糟糕的部分。

我得到了关于IoC有什么好处的回答,这不是我的要求。我的目的是了解为什么这么多开发人员更喜欢使用这样的XML文件,而不是依靠Java源来编写对象的构造。
幸运的是,我发现这种方法正在被解雇(或至少减少),有利于Spring注释和/或基于Java源代码的其他框架(如已提到的Guice)。

答案 3 :(得分:0)

控制或依赖注入的反转将帮助您控制依赖性,而无需触及源代码。你可以用XML

来做到这一点

答案 4 :(得分:0)

IOC xml实例化为您的应用程序提供了模块化。通过使用自动装配,您不必在类中显式设置成员变量/服务。可以这么想,很多类使用1..2..3..n服务,可能需要几个构造函数或工厂类,或者最糟糕的方法来获取和设置该类使用的服务。通过使用Spring,您可以在类中定义它,并且该类的使用者不需要知道或调用特殊方法。您可以使用带注释的表示法定义该bean组件,现在只需在必要时自动装配它,无需对工厂进行编码。

就XML驱动而言,我认为hyness说它最好,通过注释自动装配可以大大减轻维护xml文档的负担,如果你可以升级你的Spring版本。

答案 5 :(得分:0)

尽管使用XML文件配置应用程序可能会增加您必须满足的文件数量,从而增加了复杂性。它们确实为您提供了保持代码完整性的优势,并避免了您可能希望使用不同的Hibernate Dialect等情况下的更改等等。