Spring
写在前面
相信对于 Spring 这个模块,只要是做过 Java 开发的同学都是不陌生的,或多或少都使用过 Spring 体系的框架。对于平时自己做点小项目会写配置文件可能就行了,但是对于秋招面试只懂配置还是不行的。要明白整个框架的运行机制和流程。
这里需要说下“框架”这个问题,现在很多人的文章都说框架不重要,计算机基础才是最重要的,这一点我是非常赞同的。但是这个角度是从一个长远的角度看,但是对于一个正在秋招或者即将秋招的同学来说,如果你完全不懂 Java 开发的框架,估计会在这个上面栽跟头。建议大家把 Spring、SpringMVC、SpringBoot 了解下,当然你也可以直接看 SpringBoot,毕竟现在很多公司都已经在使用 SpringBoot 了。我学习这块比较早了,最开始学的是 SSH,后来又学了 SSM,SpringBoot 是后来实习时才学的。
本文主要说下我学习 Spring 的过程,我最开始是看某培训机构的 SSH 视频,然后做个小项目;再后来又看了某培训机构的 SSM 视频,同样做了一个小项目。后来找实习先投递的是一些小公司,都很顺利,只问你会不会用,怎么用。后来投递大公司的时候就不同了,都是问底层机制、源码之类的东西。所以就赶紧回去看书、看源码。看书的话我主要看了两本书(实际上只是翻了翻),如下图所示:
Spring 的源码可能不像 JDK 源码那样简短,比如:AOP 和 IOC 的相关源码特别的长,只能通过打断点 Debug 的方式去看,而且看了很可能会忘的很快。所以建议大家可以搜一搜一些大佬们关于 Spring 源码阅读的笔记,或者结合《Spring源码深度解析》这本书进行学习。
对于 Spring 最重要的就是 AOP 和 IOC,除此之外还有事务是面试中常问的点。其实我个人觉得对于 Spring 的学习,如果你是要秋招的同学,建议你先把 AOP 和 IOC 的大致流程搞懂,不要试图一下把 Spring 整个体系就完全弄明白了,有点不现实,也不需要在这个上面花费过多的时间,重点的几个点认真看下,面试基本上是够了的。时间充足,不需要面试的同学当然是要好好看看的。
说明:因为 Spring 的 AOP 和 IOC 的源码分享非常长,本文不对源码分析做过多阐述,如果你需要可以加我微信:pcwl_Java,备注“秋招资料”,我再分享给你。
1、使用 Spring 框架的好处是什么?
1. 轻量:Spring 是轻量的,基本的版本大约 2MB。
2. 控制反转:Spring 通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
3. 面向切面的编程(AOP):Spring 支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
4. 容器:Spring 包含并管理应用中对象的生命周期和配置。
5. MVC框架:Spring 的 Web 框架是个精心设计的框架,是 Web 框架的一个很好的替代品。
6. 事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
7. 异常处理:Spring 提供方便的 API 把具体技术相关的异常(比如由 JDBC,Hibernate or JDO 抛出的)转化为一致的 unchecked 异常。
2、解释下什么是 AOP?
AOP(Aspect-Oriented Programming,面向方面编程),可以说是 OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP 引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP 则显得无能为力。也就是说,OOP 允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如:安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在 OOP 设计中,它导致了大量代码的重复,而不利于各个模块的重用。
而 AOP 技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP 代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
使用“横切”技术,AOP 把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,它们经常发生在核心关注点的多处,而各处都基本相似。比如:权限认证、日志、事务处理。AOP 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。
3、AOP 的代理有哪几种方式?
AOP 思想的实现一般都是基于代理模式 ,在 Java 中一般采用 JDK 动态代理模式,但是我们都知道,JDK 动态代理模式只能代理接口而不能代理类。因此,Spring AOP 会按照下面两种情况进行切换,因为 Spring AOP 同时支持 CGLIB、ASPECTJ、JDK 动态代理。
1. 如果目标对象的实现类实现了接口,Spring AOP 将会采用 JDK 动态代理来生成 AOP 代理类;
2. 如果目标对象的实现类没有实现接口,Spring AOP 将会采用 CGLIB 来生成 AOP 代理类。不过这个选择过程对开发者完全透明、开发者也无需关心。
4、怎么实现 JDK 动态代理?
JDK 动态代理最核心的一个接口和方法如下所示:
- 1. java.lang.reflect 包中的 InvocationHandler 接口:
public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }
对于被代理的类的操作都会由该接口中的 invoke 方法实现,其中的参数的含义分别是:
1. proxy:被代理的类的实例;
2. method:调用被代理的类的方法;
3. args:该方法需要的参数。
使用方法首先是需要实现该接口,并且我们可以在 invoke 方法中调用被代理类的方法并获得返回值,自然也可以在调用该方法的前后去做一些额外的事情,从而实现动态代理。
- 2. java.lang.reflect 包中的 Proxy 类中的 newProxyInstance 方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
其中的参数含义如下:
1. loader:被代理的类的类加载器;
2. interfaces:被代理类的接口数组ÿ