使用 Spring Bean 连接数据库对象
Posted
技术标签:
【中文标题】使用 Spring Bean 连接数据库对象【英文标题】:Wiring Database Object with Spring Bean 【发布时间】:2016-12-24 12:14:47 【问题描述】:在 Spring in Action 一书中,有一个 Spring Bean 的例子。它使用Compact Disc
类比。当应用程序需要"The Beatles" album
时,它会创建"The Beatles" album bean
以及其他相册。
-
如果数据库中有
n
相册,那么我应该创建n
相册bean 吗?
如果不是,n
的相册在应用中是如何表示的?它只是一个 POJO 域模型(不是 bean)吗?
使用 Spring Bean 的真正用例是什么?
【问题讨论】:
【参考方案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 容器中声明并可以从中检索的任何 对象。Foo
和 Bar
是 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】:您只需要拥有一个 Album 类并将其注释为 @Component
或通过 xml 进行。
术语bean
和POJO
可以互换。根据Spring in action 4rd edition
,Spring 努力成为一个非侵入性的框架。
(...)基于 Spring 的应用程序中的类通常没有 表明它们正在被 Spring 使用。在最坏的情况下,一个类可能会使用 Spring 的注释之一进行注释,但否则它就是一个 POJO
和
虽然 Spring 大量使用 bean 和 JavaBean 这两个词 当提到应用程序组件时,这并不意味着 Spring 组件 必须严格遵守 JavaBeans 规范。一个 Spring 组件可以是 任何类型的 POJO。
- 用例是,您可以使用 Spring 依赖注入在运行时连接您的 bean,您的应用程序可以从 Spring 的简单性、可测试性和松散耦合方面受益。李>
简而言之,您所指的 Spring bean 只是在 Spring 应用程序的上下文中使用的 POJO。如果您使用 xml 映射而不是注解,您的类将只是另一个常规 Java 类,一个普通的旧 Java 对象。
【讨论】:
那么适合Spring Beans的POJO标准是什么?以上是关于使用 Spring Bean 连接数据库对象的主要内容,如果未能解决你的问题,请参考以下文章