2

好吧,这个问题会得到很多反对...

我刚刚看到这个问题,其中一个人面临一些关于 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 - 而不是 xml - 并且不需要在运行时解析,当它编译时你已经知道它形式上是正确的(并且不会在运行时发现异常),如果您需要外部化某些配置参数,则使用属性文件(将包含真实配置)。

最重要的是:我的代码中不需要一个名为“BeanFactory”的巨大单例类,它的职责是实例化各种对象(例如与 IoC 原则无关的巨大而丑陋的服务定位器)。

所以,问题是:

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

4

6 回答 6

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 的类。您的代码没有杂乱无章的管道代码,它专注于解决业务问题。

于 2013-01-08T16:51:31.400 回答
1

一个更好的问题可能是“依赖注入的优点是什么?” 毕竟,还有其他使用纯 java 而非 XML 的依赖注入框架。(见谷歌Guice

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

于 2013-01-08T22:03:05.473 回答
1

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

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

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

我得到了关于 IoC 有什么好处的答案,这不是我问的。我的意图是/是要了解为什么这么多开发人员更喜欢拥有这样的 XML 文件,而不是依赖 Java 源代码来编程对象的构造。
幸运的是,我看到这种方法正在被摒弃(或至少减少),有利于 Spring 注释和/或其他基于 Java 源代码的框架(如已经提到的 Guice)。

于 2013-01-10T13:51:46.347 回答
0

控制反转或依赖注入将帮助您在不接触源代码的情况下控制依赖。您可以在 XML 中执行此操作

于 2013-01-08T16:56:31.160 回答
0

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

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

于 2013-01-08T17:01:15.730 回答
0

尽管使用 XML 文件来配置您的应用程序可能会通过增加您必须满足的文件数量来增加更多复杂性。它们确实为您提供了保持代码完整并避免在您可能想要使用不同的 Hibernate 方言等情况下进行更改的优势。

于 2013-01-08T17:09:00.820 回答