【问题标题】:Wiring Database Object with Spring Bean使用 Spring Bean 连接数据库对象
【发布时间】:2016-12-24 12:14:47
【问题描述】:

在 Spring in Action 一书中,有一个 Spring Bean 的例子。它使用Compact Disc 类比。当应用程序需要"The Beatles" album 时,它会创建"The Beatles" album bean 以及其他相册。

  1. 如果数据库中有n 相册,那么我应该创建n 相册bean 吗?
  2. 如果不是,n的相册在应用中是如何表示的?它只是一个 POJO 域模型(不是 bean)吗?
  3. 使用 Spring Bean 的真正用例是什么?

【问题讨论】:

    标签: java spring


    【解决方案1】:

    如果我是你,我不会将光盘类比为 Spring bean,尤其是关于你后来的问题。很明显,任何 Java 对象都可以在 Spring 中声明为 bean,无论您使用的是 XML 配置还是 Java 配置。

    假设我有这两个类:

    public class Foo {
    
        private String s;
    
        private Bar bar;
    
        // getters & setters
    
    }
    
    public class Bar {
    
        private int i;
    
        // getter & setter
    
    }
    

    我可以通过在 XML 配置文件中声明前者来使前者成为 Spring Bean:

    <bean id="foo" class="demo.Foo">
        <property name="s" value="Hello, World!" />
        <property name="bar">
            <bean class="demo.Bar">
                <property name="i" value="10" />
            </bean>
        </property>
    </bean>
    

    现在,用这两行代码:

    ApplicationContext ctx = new ClassPathXmlApplicationContext("app.xml");
    Foo foo = ctx.getBean(Foo.class);
    

    可以检索配置的 foo 对象,并设置其所有属性,包括bar。这是 Spring 的核心用例,即让您配置应用程序的构建块如何在运行时解决它们的依赖关系。最初 Spring 只关注代码之外的配置,但现在关注点略有变化,比如组件扫描和 Java 配置……

    无论如何,以这个简短的例子结束,以下代码行将打印 10:

    System.out.println(foo.getBar().getI());
    

    在这个例子中,我使用了 Foo 和 Bar,但它也可以是一个 Web 服务,一个实现一些业务逻辑的服务,一个数据库,一个 ORM 外观,一个模板引擎,一个线程池,任何东西......但是主要是处理数据对象的组件,而不是数据对象本身,尽管这是完全可能的。

    现在返回您的用例,在 Spring 应用程序中,如果我正在编写带有数据库的 Web 应用程序,我通常会拥有这些组件:控制器(Web 边界)、服务(用于业务逻辑)、一个存储库(用于查询),当然还有一个数据源。我不会在这里深入研究太多细节(例如,没有声明性事务)。请注意,使用此配置,我的 Java 代码中不会编译任何特定的数据提供程序,它仍保留在配置中:

    <bean id="cdController" class="demo.compactdisc.CdController">
        <property name="cdService" ref="cdService" />
    </bean>
    
    <bean id="cdService" class="demo.compactdisc.CdServiceImpl">
        <property name="cdRepository" ref="cdRepository" />
    </bean>
    
    <bean id="cdRepository" class="demo.compactdisc.CdRepositoryImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>
    
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test"/>
        <property name="username" value="test"/>
        <property name="password" value="s3cr3t"/>
    </bean>
    

    使用您的域,存储库会将光盘从数据库返回给服务,将服务返回给控制器,将控制器返回给用户。光盘不会被描述为 Spring bean,但肯定是来自实际 Spring bean 的参数和返回值。

    【讨论】:

    • 那么适合Spring Beans的POJO标准是什么?
    • 确实没有标准。对于所有 Spring 关心的类,该类可以声明为 final,没有默认构造函数。 POJO 与如何开发一个类有关。 POJO 是松散地遵循 JavaBeans 规范的简单对象。 Spring bean 是在 IoC 容器中声明并可以从中检索的任何 对象。 FooBar 是 POJO,被声明为 Spring bean。
    • 我的意思是,什么时候 POJO 适合 Spring Bean?示例:在文档中 DataSource 适用于 Spring Bean,但域模型不适用。
    • 用技术术语来说,POJO 总是合适的。然而,在设计方面,域对象几乎永远不会用作 bean,除非您将其声明为原型(使用 scope 属性)。我认为您混淆了 POJO 和域对象。 POJO 讲述了一个类的开发方式,领域对象讲述了这个 POJO 在您的应用程序中的作用。为简单起见,您应该考虑 Spring bean 是可以在应用程序中实现为单例的对象。 Spring bean 默认是单例的(这是默认的scope),所以从一开始就很简单。
    • 这是一种看待事物的方式。请注意,request 和 session 用于 Web 应用程序,globalSession 用于 portlet。我会将问题简化为:“我的对象是单例还是我的对象是此模板对象的原型?”但是,是的,你已经掌握了窍门。
    【解决方案2】:

    如果数据库中有 n 个专辑,那么我应该创建 n 个专辑 bean 吗?

    我认为不会。如果有 n 个专辑,那么将它们全部明确包含在您的 App.config 文件中会非常麻烦,如果这就是您所指的;但你可以。您可能会添加一个 AlbumService (@Service) @Bean 和关联的 @Repository 来处理从数据库中写入和检索它们。

    如果不是,那n张专辑如何在应用程序中表示?难道只是 POJO 域模型(不是 bean)?

    您可以拥有一个具有专辑属性的 Album @Entity bean。当您保存相册时,您需要设置属性,而不是让单个组件实现公共接口。您的数据库中将有 n 个专辑。例如,如果您只需要检索 Beatles 的一张专辑,您可以根据专辑名称进行查询。如果你想要它们,你可以做albumService.findAll();并得到一个容器。

    使用 Spring Bean 的真正用例是什么?

    Spring 是 Spring Bean 的真正用例。根据Spring IoC Container Reference

    在 Spring 中,构成应用程序主干的对象和 由 Spring IoC 容器管理的称为 bean。一颗豆子 是一个被实例化、组装和以其他方式管理的对象 一个 Spring IoC 容器。否则,豆子只是众多豆子中的一种 应用程序中的对象。 Beans,以及它们之间的依赖关系, 反映在容器使用的配置元数据中。

    我无法提供比文档中包含的内容或此 answer 中给出的更好的答案。

    【讨论】:

    • 那么适合Spring Beans的POJO标准是什么?
    • @YosuaLijantoBinar,请参阅我在答案中提供的链接中的this section。您可能“[n]注意到这个类没有什么特别之处,它是一个 POJO,不依赖于容器特定的接口、基类或注释。”
    • 我的意思是,什么时候 POJO 适合 Spring Bean?示例:在文档中 DataSource 适用于 Spring Bean,但域模型不适用。
    【解决方案3】:
    1. 您只需要拥有一个 Album 类并将其注释为 @Component 或通过 xml 进行。

    2. 术语beanPOJO 可以互换。根据Spring in action 4rd edition,Spring 努力成为一个非侵入性的框架。

    (...)基于 Spring 的应用程序中的类通常没有 表明它们正在被 Spring 使用。在最坏的情况下,一个类可能会使用 Spring 的注释之一进行注释,但否则它就是一个 POJO

    虽然 Spring 大量使用 bean 和 JavaBean 这两个词 当提到应用程序组件时,这并不意味着 Spring 组件 必须严格遵守 JavaBeans 规范。一个 Spring 组件可以是 任何类型的 POJO。

    1. 用例是,您可以使用 Spring 依赖注入在运行时连接您的 bean,您的应用程序可以从 Spring 的简单性、可测试性和松散耦合方面受益。李>

    简而言之,您所指的 Spring bean 只是在 Spring 应用程序的上下文中使用的 POJO。如果您使用 xml 映射而不是注解,您的类将只是另一个常规 Java 类,一个普通的旧 Java 对象。

    【讨论】:

    • 那么适合Spring Beans的POJO标准是什么?
    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多