本文共 2628 字,大约阅读时间需要 8 分钟。
前言:从Spring框架的名称来看,我们就知道它是一个伟大的框架,代表着“程序员的春天”。在进入Spring的细节和实战之前,明白Spring是干嘛的是至关重要的。已经学过的人一定深有体会,想要用简短的话清楚描述Spring是很困难的,至少对一个初学的人是很难理解的。同时我发现关于Spring的入门文章很少,或是讲得比较少,这也导致了很多人在学习Spring的时候有点抓不住主线,不知所云,萌生退意。本篇文章旨在讲清楚Spring是干嘛的,起一个初学引导作用,后面的每一篇文章我都会回归这些内容。
小结:Spring接管了Web应用的各个层次,至于如何配置和管理组件请往下参见Spring提供的Ioc功能。这便体现了容器框架了。
传统:
Teacher teacher=new Teacher(); teacher.setName("老师"); Student student=new Student(); student.setName("学生"); student.setTeacher(teacher);Spring:
分析1:第二种方法中我们配置了一个Student对象和一个Teacher对象,并为其注入了属性,其中Student的teacher属性指向了我们定义的Teacher对象。Spring会将这两个对象管理起来,并且将Teacher对象注入到Student对象中。现在应该稍微能够理解Spring是配置和管理bean的容器框架了吧? 分析2:那么Spring煞费苦心为我们做了这事情有什么作用呢?或者说控制反转有什么作用?
写过稍大一点的程序的人应该很有体会,到了后面,其实程序很不好扩展,不好维护。对于企业级应用更是可能出现内存管理有关的问题,十分难以排查和维护。这是我们因为代码中存在大量的重复工作用来创建具体的实现,与具体耦合了!还以上面的例子为例,现假设Student和Teacher都实现了Person接口
在传统的方式中,我们假设代码中有1000个地方出现了Person person = new Student()这个语句,接着调用person接口中的方法。有朝一日,我们想要将Student换成Teacher对象?怎么办??我们不得不对这1000处都做修改,换成Person person = new Teacher(),想想都害怕。那么假如我们用了Spring呢?那么我只要在配置文件中将person对象的实现类替换成Teacher类即可,那么对于其他依赖于person对象的类,都会得到新的Teacher对象而非Student对象。也就是说,使用Spring可以让我们方便地替换抽象的具体实现! 这类似于工厂模式。
分析3:控制反转的缺点
一种技术不可能是十全十美的,必定是有所权衡,控制反转亦是。首先,相比于直接使用new创建对象,使用Spring配置bean对象时底层框架需要使用到反射机制,这必然会带来一定的性能损耗;其次,假如我们重构的时候修改了类的路径(改了包名等),那么必须手动去XML文件中修改。
先提一下编程语言的发展历程,机器语言->汇编语言->面向过程的高级语言->面向对象的高级语言。可以看出,这是逐渐抽象和封装的过程。到了面向对象,已经能够以对象维度进行编程,现在要提到的是更上维度的面向切面编程。什么是切面呢?切面是应用中的交叉功能,也即是多次重复出现的同场景下的功能。比如需要在每次方法调用的时候打印日志,这种情况下假如我们还用面向对象的粒度去思考和编程,那么在每次方法调用时必然很累赘,会出现以下重复的模式,这样系统是难以维护的:
public void method(){ //方法调用前的日志打印 // TODO: 2016/11/11 业务逻辑 //方法调用后的日志打印 }AOP要做的事情就是将这些重复的逻辑抽离出来,怎么做呢?其实看到上面的场景,很多人就能想到代理模式了,不错,这正是Spring采用的方法。Spring可以给我们返回代理对象,实际的业务逻辑Spring会交由实际对象处理,方法调用前后的其他逻辑代码由代理对象执行。这样就能实现在方法调用的前后做一些通用的工作了(比如打日志,统计方法调用时间,事务管理等)。
当然仅有代理模式是不足的!因为Spring还需要知道需要代理的具体方法(你有时候并不是所有的方法都需要打印日志),这个时候就需要我们帮助Spring选择了。Spring提供了注解、XML多种方法帮助我们声明需要被代理的方法。AOP的具体使用后面的文章会提到。
我们可以发现,Web应用基本上都会有一些通用的功能,会有许多相似的代码。于是Spring将这些功能封装起来,只要我们需要,就可以将相应的bean配置到上下文中,那么这个组件就成为了受Spring容器管理的bean,可以通过其API使用其功能。
除了Spring提供的组件,Spring还人性化地为我们考虑到了更多的可能,允许我们集成一些优秀成熟的框架。以Hibernate为例,我们只要下载其jar包之后,将需要使用到的组件注册到Spring上下文中,那么就可以在应用中使用Hibernate的ORM映射功能。