spring框架的一些技术总结
纵观现在互联网行业,java的地位依然不可动摇,因为java拥有着的众多开发人员和适用性广,技术与解决技术大部分开源等特点,因此java依然是众多众多开发行业作为互联网开发的首选,而说到开发,我们就不等不说一下近年来最火爆的那些开源框架!
首先我们来看一下那些曾经以及现在仍然火爆的框架有哪些:
注:因为今天主要目的是讲解Spring,所以其他框架就先不详细讲解了,我改天会单开个框架专栏给大家讲解
传统行业:
SSH(Spring,Struts2,Hibernate)
作为传统行业的经典,可以说SSH框架组合现在还有很多互联网行业在用到,当然,之所以还在用,是因为有很多传统项目并没有下架,所有说很多互联网行业依然需要程序员来对这些传统业务进行维护,那么作为学习java的我们,就必然要对这个框架有所了解和应用!
进阶版:
SSJ(Spring,Struts2,Spring Data JPA)
之所以说这个SSJ的框架组合是SSH的进阶版是因为它的持久城框架从hibernate换为了Spring Data JPA,而Spring Data JPA实际上是Spring基于hibernate开发的一个JPA框架,目的是简化持久层代码,dao层只需要定义接口即可,也就是持久层面向接口开发
它归属于阿帕奇公司的一个叫做Spring Data的项目,而Spring Data的目的则是为了简化构建基于 Spring 框架应用的数据访问技术,包括非关系数据库、Map-Reduce 框架、云数据服务等等;另外也包含对关系数据库的访问支持。换句话说就是阿帕奇公司希望用Spring Data统一市面上所有的持久层框架(野心很大的说)。
至于为什么说这个还仅是进阶版,是因为Struts2的存在,Struts2确实层经风靡一时,优点众多,但可惜自从业内频繁爆出Struts2存在着严重的安全漏洞,有着数据丢失容易被攻击的消息,而且京东曾因此遭受重大损失后,就慢慢的让出了业务层一哥的位置,而京东的痛下决心替换Struts2的行为,更是加速了Struts2的没落,而改由更棒的Spring MVC所替代。
新兴互联网行业:
SSM(Spring MVC,Spring,MyBatis)
SSM框架依然都是由Apache公司提供的开源,免费的框架,具有着轻量级,依赖关系解耦,面向接口,程序稳定等优良特点。
纵观传统和新兴,我们能发现,一直有一个身影在其中,而它就是Spring,一款由Apache公司推出,Rod Johnson(spring之父)开发的优秀的免费轻量级开源框架。下面就让我们一起来了解一下。
Spring简介
Spring是分层的Java SE/EE应用 full-stack轻量级开源框架,以IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。
Spring的优势
方便解耦,简化开发
通过Spring提供的IoC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
AOP编程的支持
通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
声明式事务的支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
方便集成各种优秀框架
Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。
降低JavaEE API的使用难度
Spring对JavaEE API(如JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些API的使用难度大为降低。
Java源码是经典学习范例
Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。它的源代码无意是Java技术的最佳实践的范例。
spring的开发包
官网:http://spring.io/
下载地址:
http://repo.springsource.org/libs-release-local/org/springframework/spring
解压:(Spring目录结构:)
* docs :API和开发规范.
* libs :jar包和源码.
之前我们说了spring的重多优点,而这些优点是由Spring提供的几个强化功能实现的,而这几个功能也是Spring的极大亮点,需要我们关注,因为这些亮点几乎是我们作为程序员所应知应会的,下面我们就来看看这几个亮点分别是什么:
控制反转 - - IOC(方便解耦)
依赖注入 - - DI
切面编程 - - AOP
控制反转:
说道控制反转的解耦型,我们就需要知道一个问题,即什么是程序的耦合性?
什么是程序的耦合
我们在开发中,会写很多的类,而有些类之间不可避免的产生依赖关系,这种依赖关系称之为耦合。
有些依赖关系是必须的,有些依赖关系可以通过优化代码来解除的。请看下面的示例代码:
复制代码
/**
public class CustomerServiceImpl implements ICustomerService {
private ICustomerDao customerDao = new CustomerDaoImpl();
}
复制代码
上面的代码表示:业务层调用持久层,并且此时业务层在依赖持久层的接口和实现类。如果此时没有持久层实现类,编译将不能通过。这种依赖关系就是我们可以通过优化代码解决的。
再比如:
下面的代码中,我们的类依赖了MySQL的具体驱动类,如果这时候更换了数据库品牌,我们需要改源码来修改数据库驱动。这显然不是我们想要的。
复制代码
public class JdbcDemo1 {
/**
* JDBC操作数据库的基本入门中存在什么问题?
* 导致驱动注册两次是个问题,但不是严重的。
* 严重的问题:是当前类和mysql的驱动类有很强的依赖关系。
* 当我们没有驱动类的时候,连编译都不让。
* 那这种依赖关系,就叫做程序的耦合
*
* 我们在开发中,理想的状态应该是:
* 我们应该尽力达到的:编译时不依赖,运行时才依赖。
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
//1.注册驱动
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName(“com.mysql.jdbc.Driver”);
//2.获取连接
//3.获取预处理sql语句对象
//4.获取结果集
//5.遍历结果集
}
}
复制代码
解决程序耦合的思路
当是我们讲解jdbc时,是通过反射来注册驱动的,代码如下:
Class.forName(“com.mysql.jdbc.Driver”);
这时的好处是,我们的类中不再依赖具体的驱动类,此时就算删除mysql的驱动jar包,依然可以编译。但是因为没有驱动类,所以不能运行。
不过,此处也有个问题,就是我们反射类对象的全限定类名字符串是在java类中写死的,一旦要改还是要修改源码。
解决这个问题也很简单,使用配置文件配置。
工厂模式解耦
在实际开发中我们可以把所有的dao和service和action对象使用配置文件配置起来,当启动服务器应用加载的时候,通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。
控制反转-Inversion Of Control
上面解耦的思路有2个问题:
1、存哪去?
分析:由于我们是很多对象,肯定要找个集合来存。这时候有Map和List供选择。 到底选Map还是List就看我们有没有查找需求。有查找需求,选Map。
所以我们的答案就是:
在应用加载时,创建一个Map,用于存放action,Service和dao对象。
我们把这个map称之为容器。
2、还是没解释什么是工厂?
工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。
原来:
我们在获取对象时,都是采用new的方式。是主动的。
现在:
我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。
这种被动接收的方式获取对象的思想就是控制反转,它是spring框架的核心之一。
它的作用只有一个:削减计算机程序的耦合。
学习了上面的控制反转,我们得出了一个结论:Spring是利用工厂模式的形式完成了解耦!使我们从原来的主动调用者,变为了被动的获取者的转变。(一些面试时常问这个问题)
Spring的依赖注入
依赖注入的概念
它是spring框架核心ioc的具体实现方式。简单的说,就是坐等框架把对象传入,而不用我们自己去获取。从此,当我们需要用到一个对象时,只需从从spring容器中获取即可(前提是你事先把那个对象交给了spring容器管理,即在xml中事先配置)
依赖注入的两种方式:构造函数注入和set方法注入
1 构造函数注入
顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让spring框架来为我们注入
2 set方法注入
顾名思义,就是在类中提供需要注入成员的set方法。
Spring的切面编程–AOP
什么是AOP?
AOP:全称是Aspect Oriented Programming即:面向切面编程。
AOP的作用及优势
作用:
在程序运行期间,不修改源码对已有方法进行增强。
优势:
减少重复代码 提高开发效率 维护方便
AOP的实现方式
使用动态代理技术
说道切面编程,也许有很多人会很困惑,编程可以理解,而什么是切面呢?下面我们来详细的慢慢解释一下:
首先,我们可以设想一下,在我们原先的项目中service层的一些需要事物控制的方法内,是不是一个方法内就需要写一段事物控制代码?这就导致了一个问题:
我们的事务控制是重复性的代码。
为什么这么说呢?因为一个类中就需要些多个事物控制代码了,那么如果有多个业务了,每个业务类中就都会有这些重复的代码。因此我们得出了这个结论。
思考:
我们怎么解决呢?:动态代理
动态代理回顾:
动态代理的特点:
字节码随用随创建,随用随加载。它与静态代理的区别也在于此。因为静态代理是字节码一上来就创建好,并完成加载。装饰者模式就是静态代理的一种体现。
动态代理常用的两种方式:
基于接口的动态代理:
提供者:JDK官方的Proxy类。
要求:被代理类最少实现的一个接口。
基于子类的动态代理:
提供者:第三方的CGLib,如果报asmxxxx异常,需要导入asm.jar。
要求:被代理类不能用final修饰的类(最终类)。
Spring中的AOP
关于代理的选择:
在spring中,框架会根据目标类是否实现了接口来决定采用哪种动态代理的方式。
AOP相关术语:
Joinpoint(连接点):
所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点。
Pointcut(切入点):
所谓切入点是指我们要对哪些Joinpoint进行拦截的定义。
Advice(通知/增强):
所谓通知是指拦截到Joinpoint之后所要做的事情就是通知。
通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
Introduction(引介):
引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field。
Target(目标对象):
代理的目标对象。
Weaving(织入):
是指把增强应用到目标对象来创建新的代理对象的过程。
spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。
Proxy(代理):
一个类被AOP织入增强后,就产生一个结果代理类。
Aspect(切面):
是切入点和通知(引介)的结合。
学习spring中的AOP要明确的事
a、开发阶段(我们做的)
编写核心业务代码(开发主线):大部分程序员来做,要求熟悉业务需求。
把公用代码抽取出来,制作成通知。(开发阶段最后再做):AOP编程人员来做。
在配置文件中,声明切入点与通知间的关系,即切面。:AOP编程人员来做。
b、运行阶段(Spring框架完成的)
Spring框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。
总结:
面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。
编后语:Spring框架的内容太多了,本人目前也在学习中,以上内容仅是我根据自己目前掌握的内容以及一些借鉴资料编写,不足以确保一点不差,所以如有不对的地方,欢迎各位朋友指正,希望我们能共同进步。