Spring依赖注入技术的发展

回顾Spring框架的历史,您会发现实现依赖注入的方式在每个发行版中都在增加。

如果您使用该框架已经超过一个月,那么在这篇回顾性文章中可能不会发现任何有趣的东西。 除了Scala中的最后一个示例,没有其他希望,这种语言在Spring中意外地很好用。

首先是XML [ 全文 ]:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd "><bean id="foo" class="com.blogspot.nurkiewicz.Foo"><property name="bar" ref="bar"/><property name="jdbcOperations" ref="jdbcTemplate"/></bean><bean id="bar" class="com.blogspot.nurkiewicz.Bar" init-method="init"/><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="org.h2.Driver"/><property name="url" value="jdbc:h2:mem:"/><property name="username" value="sa"/></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><constructor-arg ref="dataSource"/></bean>
</beans>

这个简单的应用程序仅获取H2数据库服务器时间并以完整格式打印它:

public class Foo {private Bar bar;private JdbcOperations jdbcOperations;public String serverTime() {return bar.format(jdbcOperations.queryForObject("SELECT now()", Date.class));}public void setBar(Bar bar) {this.bar = bar;}public void setJdbcOperations(JdbcOperations jdbcOperations) {this.jdbcOperations = jdbcOperations;}
}
public class Bar {private FastDateFormat dateFormat;public void init() {dateFormat = FastDateFormat.getDateTimeInstance(FULL, FULL);}public String format(Date date) {return dateFormat.format(date);}
}

这段代码有些令人不安。 首先,令人惊讶的是有很多XML。 与类似的EJB 2.1应用程序相比,它仍然要少一些(此代码在2006年的Spring 1.2.6上进行了微小的更改 ),但是感觉很不对。 公共设置者更加令人不安–为什么我们被迫在任何时候任何人都公开覆盖对象依赖的能力? 顺便说一下,我从来没有真正理解过为什么为什么在使用tag时Spring不允许直接将依赖项注入到私有字段中,因为这样做可能……

批注 [ 全文 ]

Java 5和Spring 2.5带来了对注释驱动的依赖注入的支持:

<context:annotation-config/><!-- or even: --><context:component-scan base-package="com.blogspot.nurkiewicz"/>

从第一行开始,您不再需要在XML中定义<property>标签,只需定义<bean>。 该框架将获取标准的@Resource注释。 将其替换为第二行,甚至根本不需要在XML中指定bean:

@Service
public class Foo {@Resourceprivate Bar bar;@Resourceprivate JdbcOperations jdbcOperations;public String serverTime() {return bar.format(jdbcOperations.queryForObject("SELECT now()", Date.class));}
}
@Service
public class Bar {private FastDateFormat dateFormat;@PostConstructpublic void init() {dateFormat = FastDateFormat.getDateTimeInstance(FULL, FULL);}public String format(Date date) {return dateFormat.format(date);}
}

当然,您不会留下深刻的印象! 尼尔·诺维(Nihil Novi) 。 另外,我们仍然必须使用XML,因为我们无法控制第三方类(例如数据源和JdbcTemplate ),因此无法对其进行注释。 但是Spring 3.0引入了:

@Configuration [ 完整源代码 ]

我已经在探索@ Configuration / @ Bean支持,因此这次请重点关注如何启动应用程序上下文。 您看到对XML文件的任何引用吗? applicationContext.xml描述符完全消失了:

@ComponentScan("com.blogspot.nurkiewicz")
public class Bootstrap {private static final Logger log = LoggerFactory.getLogger(Bootstrap.class);@Beanpublic DataSource dataSource() {final BasicDataSource dataSource = new BasicDataSource();dataSource.setDriverClassName("org.h2.Driver");dataSource.setUrl("jdbc:h2:mem:");dataSource.setUsername("sa");return dataSource;}@Beanpublic JdbcTemplate jdbcTemplate() {return new JdbcTemplate(dataSource());}public static void main(String[] args) {final AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContext(Bootstrap.class);final Foo foo = applicationContext.getBean(Foo.class);log.info(foo.serverTime());applicationContext.close();}
}

如您所见,Spring从使用大量XML到不使用XML的框架走了很长的路。 但最令人兴奋的部分是您可以使用喜欢的任何样式,甚至可以将它们混合使用。 您可以使用旧版Spring应用程序并开始使用批注或切换到XML,因为上帝知道这里或那里的原因。

我没有提到的一种技术是构造函数注入。 它有一些很大的好处(请参阅使用构造函数进行依赖注入? ),例如将依赖关系标记为最终的并禁止创建未初始化对象的能力:

@Service
public class Foo {private final Bar bar;private final JdbcOperations jdbcOperations;@Autowiredpublic Foo(Bar bar, JdbcOperations jdbcOperations) {this.bar = bar;this.jdbcOperations = jdbcOperations;}//...}

我希望构造函数注入,但是再次感到有点失望。 每个对象依赖项都需要(a)构造函数参数,(b)最终字段和(c)构造函数中的赋值操作。 我们最后得到十行代码,这些行什么都不做。 这个健谈的代码克服了所有优点。 当然,任何对象都不应具有超过(在这里输入您的数字)的依赖关系-借助构造函数注入,您会立即看到该对象具有太多的依赖关系-但我仍然发现此代码引入了太多的仪式。

用Scala注入Spring构造函数 [ 完整源代码 ]

Scala的一个功能完全适合Spring框架:默认情况下,任何Scala对象的每个参数都会创建与该参数相同的最终字段。 对我们而言,这意味着什么? 看看翻译成Scala的Foo类:

@Service
class Foo @Autowired() (bar: Bar, jdbcOperations: JdbcOperations) {def serverTime() = bar.format(jdbcOperations.queryForObject("SELECT now()", classOf[Date]))}

认真吗 但是……怎么了? 在这里深入了解Scala的优势之前,请看一下Java反编译器生成的等效Java代码:

@Service
public class Foo implements ScalaObject
{private final Bar bar;private final JdbcOperations jdbcOperations;@Autowiredpublic Foo(Bar bar, JdbcOperations jdbcOperations){this.bar = bar;this.jdbcOperations = jdbcOperations;}public String serverTime(){return this.bar.format(this.jdbcOperations.queryForObject("SELECT now()", Date.class));}}

与我们用Java编写的代码几乎完全相同。 拥有所有优势:依赖最终将使我们的服务真正不变和无状态; 依赖是私有的,不会暴露给外界; 实际上,不需要额外的代码来管理依赖项:只需添加构造函数参数,Scala就会处理其余的工作。

总结一下–您拥有广泛的可能性。 从XML到Java代码再到Scala。 最后一种方法实际上很诱人,因为它使您摆脱了所有样板,并使您可以专注于业务功能。 完整的源代码可在我的GitHub存储库中找到,每个步骤都带有标签,因此您可以比较和选择最喜欢的方法。

参考资料: NoBlogDefFound的JCG合作伙伴Tomek Nurkiewicz提供的Spring依赖注入技术的 发展

编码愉快! 不要忘记分享!

相关文章:

  • Java最佳实践系列
  • 正确记录应用程序的10个技巧
  • 每个程序员都应该知道的事情
  • 生存在狂野西部开发过程中的9条提示
  • 软件设计法则
  • Java Fork / Join进行并行编程

翻译自: https://www.javacodegeeks.com/2011/09/evolution-of-spring-dependency.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS encode decode

网上查到的全都是escape&#xff0c;和需要的编码不是一回事&#xff0c;好不容易找到的结果 保存下来以备以后使用js对文字进行编码涉及3个函数&#xff1a;escape,encodeURI,encodeURIComponent&#xff0c;相应3个解码函数&#xff1a;unescape,decodeURI,decodeURIComponen…

流媒体服务器 笔记

1.sip服务器回SBC Port Unreachable 说明转码器接收RTCP的端口没有打开 转载于:https://www.cnblogs.com/luoyinjie/p/7219359.html

力扣151. 翻转字符串里的单词

给你一个字符串 s &#xff0c;逐个翻转字符串中的所有 单词 。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 请你返回一个翻转 s 中单词顺序并用单个空格相连的字符串。 没思路&#xff0c;看到的官方给的&#xff0c;简洁明了&…

Spring 3 HornetQ 2.1集成教程

通过Spring框架使用JBoss的新超高性能消息传递系统。 HornetQ是一个开放源代码项目&#xff0c;用于构建多协议&#xff0c;可嵌入&#xff0c;非常高性能的集群异步消息传递系统。 它是用Java编写的&#xff0c;并且可以在具有Java 5或更高版本运行时的任何平台上运行。 Horn…

B/S和C/S架构图解

软件&#xff1a;B/S和C/S两种架构模式。接下来用三张图片解释&#xff0c;什么是B/S什么是C/S。 图片一&#xff1a;软件架构模式 图片二&#xff1a;C/S结构模式 图片三&#xff1a;B/S结构模式 相信图解胜过冗长文字的解释&#xff0c;什么是B/S什么是C/S一目了然。 转载于:…

557. 反转字符串中的单词 III

给定一个字符串&#xff0c;你需要反转字符串中每个单词的字符顺序&#xff0c;同时仍保留空格和单词的初始顺序。 class Solution {public String reverseWords(String s) {StringBuffer res new StringBuffer();int length s.length();int i 0;while(i < length){int …

休眠陷阱

我已经使用Hibernate已有一段时间了&#xff0c;当我一段时间不使用Hibernate项目时&#xff0c;发现自己犯的错误与上次相同。 因此&#xff0c;这是我的监视清单&#xff0c;希望对其他人也有用。 实现hashCode和equals 一般而言&#xff0c;应该始终实现这些方法&#xff…

HDU 5371 Hotaru's problem (Manacher,回文串)

题意&#xff1a;给一个序列&#xff0c;找出1个连续子序列&#xff0c;将其平分成前&#xff0c;中&#xff0c;后等长的3段子序列&#xff0c;要求【前】和【中】是回文&#xff0c;【中】和【后】是回文。求3段最长为多少&#xff1f;由于平分的关系&#xff0c;所以答案应该…

bash 与 dash

Ubuntu 的 bash和dash的区别 什么是bash &#xff1f; Bash(GNU Bourne-Again Shell)是许多Linux平台的内定Shell&#xff0c;事实上&#xff0c;还有许多传统UNIX上用的Shell&#xff0c;像tcsh、csh、ash、bsh、ksh等 等&#xff0c;Shell Script大致都类同&#xff0c;当您学…

350. 两个数组的交集 II

给你两个整数数组 nums1 和 nums2 &#xff0c;请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数&#xff0c;应与元素在两个数组中都出现的次数一致&#xff08;如果出现次数不一致&#xff0c;则考虑取较小值&#xff09;。可以不考虑输出结果的顺序。 来源&a…

Eclipse:如何附加Java源代码

在Eclipse中&#xff0c;当您按Ctrl按钮并单击任何类名称时&#xff0c;IDE会将您带到该类的源文件。 这是项目中具有的类的正常行为。 但是&#xff0c;如果您也希望Java核心类具有相同的行为&#xff0c;则可以通过将Java源代码附加到Eclipse IDE来实现。 一旦附加了源代码&a…

【树状数组】

问题的提出&#xff1a;是否可以用线性数据结构的方法解决动态统计子树权和的问题呢&#xff1f; 有的&#xff0c;树状数组。 假设当前数组为a[]&#xff0c;元素个数为n。 1. 子区间的权和数组为sum&#xff0c;那么数组a[]中 i 到 j这段区间的数组元素和为sum[i,j] a[k]的累…

2013VS快捷键

VS2013常用快捷键&#xff1a; 1.回到上一个光标位置/前进到下一个光标位置 1&#xff09;回到上一个光标位置&#xff1a;使用组合键“Ctrl -”&#xff1b; 2&#xff09;前进到下一个光标位置&#xff1a;“Ctrl Shift - ”。 2.复制/剪切/删除整行代码 1&#xff09;如果…

GWT,GWT-Ext(SmartGWT),GXT(Ext GWT)常见任务

我在我们的JCG合作伙伴之一UI-Programming博客上浏览了一些旧文章&#xff0c;并注意到有很多简短的文章&#xff0c;介绍了如何使用GWT&#xff0c;GWT-Ext&#xff08;SmartGWT&#xff09;和GXT&#xff08;Ext GWT&#xff09;执行一些常见任务。 &#xff09;。 我相信它们…

h.264 去块滤波

块效应及其产生原因 我们在观看视频的时候&#xff0c;在运动剧烈的场景常能观察到图像出现小方块&#xff0c;小方块在边界处呈现不连续的效果&#xff08;如下图&#xff09;&#xff0c;这种现象被称为块效应&#xff08;blocking artifact&#xff09;。 首先我们需要搞清楚…

android开发的知识点(一)

1.android中背景图的设置&#xff1a; 将背景图放入到项目中的res/drawable-hdpi或res/drawable-mdpi或res/drawable-xhdpi或res/drawable-xxhdpi等任一文件夹下。然后在layout的xml文件夹下使用android:background"drawable/背景图名"&#xff0c;其中背景图必须是p…

566. 重塑矩阵

在 MATLAB 中&#xff0c;有一个非常有用的函数 reshape &#xff0c;它可以将一个 m x n 矩阵重塑为另一个大小不同&#xff08;r x c&#xff09;的新矩阵&#xff0c;但保留其原始数据。 给你一个由二维数组 mat 表示的 m x n 矩阵&#xff0c;以及两个正整数 r 和 c &…

RabbitMQ播放模块! 构架

RabbitMQ提供了具有可预测且一致的吞吐量和延迟的高可用性&#xff0c;可伸缩和便携式消息系统。 RabbitMQ是AMQP &#xff08;业务消息传递的开放标准&#xff09;的领先实现 &#xff0c;并且通过适配器支持XMPP&#xff0c;SMTP&#xff0c;STOMP和HTTP来进行轻量级Web消息传…

Cyclic Nacklace - HDU 3746(next求循环节)

题目大意&#xff1a;给你一些串&#xff0c;问如果想让这个串里面的循环节至少循环两次&#xff0c;需要添加几个字符&#xff08;只能在最前面或者最后面添加&#xff09;。比如ababc 需要添加5个就是添加ababc。 分析&#xff1a;其实字符串的长度len-next[len] 最小循环节…

Xuggler开发教程

大家好&#xff0c; 在这篇文章中&#xff0c;我想介绍JavaCodeGeeks上的一些很酷的新教程。 他们将讨论与Xuggler &#xff0c; FFmpeg和Wowza进行媒体&#xff08;音频/视频&#xff09;操纵的方式。 我将在这篇文章中跟踪所有相关的教程。 您可以通过查看Pat较早的关于使用…