本课程内容由浅入深、知识点全面,同时结合了作者丰富的实战经验,行文流畅,是不可多得的学习资料。
——尹吉欢,《Spring Cloud 微服务:全栈技术与案例解析》一书作者,极部落 Java 开发者大会分享嘉宾
Spring MVC 是一款基于动作的 MVC 框架,作为当下主流的框架之一,其具有可配置、非侵入的特点,代码复用性高,可定制绑定模型数据和验证器,是从事 Java 后端开发人员应该要掌握的技术。
本课程内容从如何使用 Spring MVC 进行实际开发的角度出发,通过剖析底层原理 + 实际案例的方式详细讲解了 Spring MVC 的常用技能点,以达到掌握底层原理的同时能够快速上手进行开发的目的。
宁楠,资深 Java 开发工程师、技术公众号原创博主、知识星球常驻嘉宾、讲师。曾就职于某大型互联网公司,历任高级工程师、技术总监、创业公司 CTO;曾参与研发手游欢乐碰碰熊后台数据管理系统、某医疗系统区域数据采集交换平台等项目,对 Java Web 编程有着丰富的经验和独到的见解,并热衷于分享编程干货,著作《Java 极简编程》一书即将出版。
大家好,我是宁楠,资深 Java 开发工程师,曾就职于某大型互联网公司,历任高级工程师、技术总监、创业公司 CTO,对 Java Web 编程有着丰富的经验和独到的见解。
首先问大家一个问题,我们不断学习新技术、不断提高自己能力的目的是什么?可能有一小撮人单纯追求技术带来的快乐,但是以我个人的观察经验,大部分人是为了找到更好的工作、拿到更高的薪资。
既然是这样,我们在选择学习一门技术的时候,先要考虑的是这门技术的市场需求量如何,以及企业需要什么技术,然后再判断这门技术值不值得花精力学习。因此,请记住一句话,尽量只学实用的技术。
1. 关于 Spring MVC 技术的招聘信息
打开 Boss 直聘、智联招聘等网站,搜索 Java 相关的岗位,大部分招聘信息的任职要求如下图所示:
上面几则招聘信息表明,如果去应聘 Java 开发工程师的岗位,无论是初级开发师,还是有一定经验的中高级开发师,多多少少需要掌握 Spring MVC 框架技术。在当下互联网技术日新月异的环境下,大部分企业还在用 Spring MVC 框架进行项目研发。由此看来,我们不能仅仅掌握 Spring MVC 的基本用法就可以了,更需要深入了解它,以便更好地适应企业的开发需求,同时提升自我价值。
2. Spring MVC 的重要性
作为当前流行的 MVC 框架,Spring MVC 框架的优点就不再赘述了,同时它是 Spring 框架体系的一个分支产品,以 Spring IoC 为基础,并利用容器的特性来简化其配置。Spring 是 Java 开发领域非常重要的框架,绝大部分的企业级应用程序都使用 Spring 来构建体系,而 Spring MVC 相当于 Spring 的一个子模块,可以很好地和 Spring 整合起来进行开发。
Spring MVC 是我个人在开发 Web 应用时的不二之选。回想起几年前开始学习 Spring MVC 技术的时候,苦于网上没有太多详细且实用的教程,大多泛泛而谈、偏理论而轻实践,或者只是讲解了 Spring MVC 的部分常用功能,内容不够完整。自己在学习摸索的过程中遇到了很多问题,也踩过很多坑,这对于初学者来说,是效率非常低的一种方式。我们在竞争如此激烈的行业中,最应该追求的就是高效率,写代码也罢、学技术也罢,都是这样,只有做到事半功倍才有更多时间和精力去学习新技术,从而进一步提高自己的能力。
《Spring MVC 实战手册》。
Spring MVC 技术现在已成为主流,但遗憾的是,网上相关详细全面且实用的教程还是很少,这对于初学者来说,学习成本依旧很高。作为一个热衷于分享干货的原创博主,我将自己长时间以来学习使用 Spring MVC 框架的经验和技巧整理成册,以 GitChat 达人课的形式分享给大家。
我本人比较反感长篇大论讲概念、没有多少实际干货的教程。再次强调,我们学习的目的主要在于应用,而不在于研究理论,所以我的写作风格是偏向于实际应用的,可以快速上手,同时辅以底层原理的讲解。整个课程深入浅出、通俗易懂,案例式 + 专题式的风格带领大家快速上手 Spring MVC。
整个课程的设计兼顾初学者和有一定经验的开发人员,前半部分详细讲解 Spring MVC 框架在实际开发中需要用到的技能点,所选取案例全部是我个人在开发中遇到的典型问题,实用性很强。
后半部分在前面的基础上进行了延伸扩展,包括当下主流的 NoSQL 数据库 MongoDB 的讲解,如何使用 Spring Data 框架操作 MongoDB,Nginx 搭建 Tomcat 集群实现负载均衡。
课程的最后,我把涉及的知识点进行了整合,来完成一个权限管理的实战项目,通过这套 Spring MVC + Layui + Spring Data + MongoDB 技术选型可以直接应用到实际开发中。
权限管理是企业比较关注的,也是面试中经常会问到的重点问题,所以选择实现一个权限管理的功能模块,也是给大家添加一个求职砝码,让你更具竞争力。
权限管理模块用来设置系统的安全策略,用户只能访问已授权的资源,未授权的资源无法访问,可在后台动态设置用户的资源授权,通过将各种权限分配给角色,再将角色赋予用户的方式来完成。
本系统持久层使用的是 MongoDB 数据库,业务实现使用的是 Spring MVC + Spring Data 技术选型,前端使用的是 Layui 框架,具体效果图如下所示。
本课程内容分为四大部分,共计 23 课。
第一部分:Spring IoC 专题(第 01 ~ 04 课)
万丈高楼平地起。IoC 作为 Spring 框架体系的底层容器,是我们必须要掌握的基础,这部分内容将讲解 Spring IoC 的原理及实际应用。
第二部分:Spring MVC 详解(第 05 ~ 17 课)
技能梳理、突破重点。有了前面的 Spring IoC 基础,接下来进入本课程的重头戏,这部分内容将详细讲解 Spring MVC 的使用,涵盖了实际开发中常用的技能点,理论结合实践的方式不仅仅让读者掌握基本的概念,同时具备使用 Spring MVC 开发项目的能力。
第三部分:MongoDB 专题(第 18 ~ 21 课)
百尺竿头,横向扩展。在实际开发中,Spring MVC 需要配合数据库来实现完整的业务功能,这部分内容将讲解当前主流的 NoSQL 数据库 MongDB,包括其安装及使用。
第四部分:项目实战(第 22 ~ 23 课)
融合贯通,更上一层楼。这部分内容将讲解 Nginx 搭建 Tomcat 集群,以及使用 Spring MVC + Layui + Spring Data + MongoDB 的技术选型来完成一个项目实战。
希望大家学完本系列课程后,可以快速了解并掌握 Spring MVC 在项目中最常用的技能点,以及在实际开发中 Spring MVC 与其他技术的整合。同时学会使用一个完整的技术选型,可以直接应用到实际项目中,具备使用 Spring MVC 开发项目的能力。预祝学习愉快~
点击了解《Spring MVC 实战手册》。
Spring 是一个企业级开发框架,为解决企业级项目开发过于复杂而创建的,框架的主要优势之一就是分层架构,允许开发者自主选择组件。
Spring 的两大核心机制是 IoC(控制反转)和 AOP(面向切面编程),从开发的角度讲,我们使用 Spring 框架就是用它的 IoC 和 AOP。
这里我们来详细了解 IoC,它是 Spring 框架的灵魂,非常重要,理解了 IoC 才能掌握 Spring 框架如何使用。
IoC 也叫控制反转,首先从字面意思理解,什么叫控制反转?反转的是什么?
在传统的程序开发中,当需要调用对象时,通常由调用者来创建被调用者的实例,即对象是由调用者主动 new 出来的。
但在 Spring 框架中创建对象的工作不再由调用者来完成,而是交给 IoC 容器来创建,再推送给调用者,整个流程完成反转,因此是控制反转。
举个超市购物的例子。
传统方式:假如去超市买东西,我们需要先选择商品,然后用准备好的袋子或者购物袋把商品提回来。
IoC:只需要把袋子放在家门口,超市会自动在袋子里装满你需要的商品,然后打开袋子直接用就可以了。
我们通过创建一个 Student 对象来讲解 IoC 的使用。
(1)创建 Student 类:
public class Student { private int id; private String name; private int age;}
(2)在测试方法中调用构造函数创建对象:
Student student = new Student();
准备工作:
程序思路:
代码:
IoC 容器可以调用无参构造或者有参构造来创建对象,我们先来看无参构造的方式。
1. 无参构造
配置一个 bean 标签
调用 API 获取对象
Spring 提供了两种方式来获取对象:ID 或者运行时类。
(1)通过 ID 获取对象
//1.加载 spring.xml 配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");//2.通过 id 值获取对象Student stu = (Student) applicationContext.getBean("stu");System.out.println(stu);
程序在加载 spring.xml 时创建 stu 对象,通过反射机制调用无参构造函数,所有要求交给 IoC 容器管理的类必须有无参构造函数。
可以看到,此时 stu 对象的属性全部为空,因为调用无参构造只会创建对象而不会进行赋值,如何赋值呢?只需要在 spring.xml 中进行相关配置即可。
添加 property 标签:name 对应属性名,value 是属性的值。
若包含特殊字符,比如 name="<张三>",则使用]]>
进行配置。
]]>
Spring 通过调用每个属性的 setter 方法来完成属性的赋值,因此实体类必须有 setter 方法,否则加载时报错,getter 方法可省略。
(2)通过运行时类获取对象
//1.加载 spring.xml 配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");//2.通过运行时类获取对象Student stu = applicationContext.getBean(Student.class);System.out.println(stu);
此方法有一个弊端,当 spring.xml 中配置两个 Student 的 bean 时程序报错,因为此时两个 bean 都是由 Student 类生成的,IoC 容器无法将两个 bean 都返回,必须指定一个唯一的 bean。
]]>
以上是 IoC 容器通过无参构造创建对象的方式,同时 IoC 容器也可以调用有参构造来创建对象。
2. 有参构造
首先在实体类中创建有参构造:
public Student(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age;}
在 spring.xml 中进行配置:
此时,IoC 容器会根据 constructor-arg 标签去加载对应的有参构造函数,创建对象并完成属性赋值。
name 的值需要与有参构造的形参名对应,value 是对应的值。
除了使用 name 对应的参数外,还可以通过下标 index 对应。
以上是 IoC 容器通过有参构造创建对象的方式,获取对象同样有两种方式可以选择:ID 和运行时类。
创建(班级)Classes 类:
public class Classes { private int id; private String name;}
在 Student 类中添加 Classes 属性:
public class Student { private int id; private String name; private int age; private Classes classes;}
spring.xml 中配置 classes 对象,然后将该对象赋值给 stu 对象:
]]>
在 spring.xml 中,通过 ref 属性将其他 bean 赋给当前 bean 对象,这种方式叫做依赖注入(DI),是 Spring 非常重要的机制。DI 是将不同对象进行关联的一种方式,是 IoC 的具体实现方式,通常 DI 和 IoC 是紧密结合在一起的,所以一般说的 IoC 包括 DI。
Classes 类中添加 List\
public class Classes { private int id; private String name; private List students;}
spring.xml 中配置 2 个 student 对象、1 个 classes 对象,并将 2 个 student 对象注入到 classes 对象中。
]]>
集合属性通过 list 标签和 ref 标签完成注入,ref 的 bean 属性指向需要注入的 bean 对象。
IoC 是 Spring 的核心,很重要,使用 Spring 开发项目时,控制层、业务层、DAO 层都是通过 IoC 来完成依赖注入的。
点击了解《Spring MVC 实战手册》。
这节课讲解了 Spring IoC 的基本概念以及如何使用,IoC 是 Spring 的核心,这很重要。使用 Spring 开发项目时,控制层、业务层、DAO 层都是通过 IoC 来完成依赖注入的。
点击这里下载源码
第01课介绍了 Spring 的 IoC,即控制反转,当程序中需要使用对象时,直接通过 Spring 容器来获取对象,并通过 DI 完成对象之间的注入关系。这一课我们继续学习 IoC 的相关知识。
bean 是根据 scope 来生成的,表示 bean 的作用域。
scope 有 4 种类型,具体如下。
其中,后两个只适用于 Web 项目,在大多数情况下,我们只会使用 singleton 和 prototype 两种 scope,并且 scope 的默认值是 singleton。
我们通过一个例子来学习这两种配置的区别。
(1)创建 User 实体类:
public class User { private int id; private String name; private int age; public User() { System.out.println("创建了 User 对象"); } }
(2)在 spring.xml 配置 User 的实例化 bean:
(3)测试类中通过 Spring 容器获取两个 User 实例化对象 user1 和 user2,并且通过 == 方法判断是否为同一个对象。
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User user = (User) applicationContext.getBean("user");User user2 = (User) applicationContext.getBean("user");System.out.println(user == user2);
从运行结果可知,打印 true,并且 User 的构造函数只执行了一次,表示 user1 和 user2 是同一个对象,所以 scope 默认值为 singleton,即默认通过 Spring 容器创建的对象都是单例模式。
修改 spring.xml 中的配置,将 scope 改为 prototype。
执行代码,结果如下:
可以看到,调用了两次构造函数,并且 == 的结果为 false,表示现在的 user1 和 user2 是两个对象。
《Spring MVC 实战手册》。
与 Java 的继承不一样,但思想很相似,子 bean 可以继承父 bean 中的属性。
看到这里,有读者会问子 bean 可以继承父 bean 中的方法吗?
其实这里不存在方法的继承,Spring 的继承是在对象层面进行操作的,即两个 bean 来自同一个类,所以方法是一样的,不存在继承关系。
(1)spring.xml 中配置两个 user bean,并建立继承关系:
(2)运行代码,结果如下:
User user2 = (User) applicationContext.getBean("user2");System.out.println(user2);
可以看到,创建了两个 User 对象 user1 和 user2,并且 user2 继承了 user1 的所有属性。
user2 在继承 user1 所有属性的基础之上,还可以对属性进行覆盖,直接在 spring.xml 中添加 property 即可。
再次运行代码,得到如下结果:
name 属性已经被修改为李四,完成覆盖。
有读者可能会问,Spring 中的 bean 能不能在不同类之间继承?
答案是可以的,但是需要这两个类的属性列表完全一致,否则会报错,在实际开发中并不会使用到这种方式。
与继承类似,依赖也是 bean 和 bean 之间的一种关联方式,配置依赖关系后,被依赖的 bean 一定先创建,然后再创建依赖的 bean。
我们还是通过代码来理解一下吧。
(1)创建 Car 实体类:
public class Car { private int id; private String brand; public Car() { System.out.println("创建了 Car 对象"); }}
(2)在 spring.xml 中配置 User bean、Car bean:
(3)测试类中获取两个 bean:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User user = (User) applicationContext.getBean("user");Car car = (Car) applicationContext.getBean("car");
从运行结果可知,先创建 User,后创建 Car,这是由 spring.xml 中 bean 的配置顺序来决定的,先到先得,先配置 User bean,所以先创建了 User 对象。
现在修改 spring.xml 配置,User 依赖 Car,设置 depends-on 属性。
再次运行代码,从结果可知,先创建 Car,后创建 User,因为 User 依赖于 Car,所以必须先创建 Car 对象,User 对象才能完成依赖。
一般开发中,数据库的配置会保存在一个 properties 文件中,便于维护,如果使用 Spring 容器来生成数据源对象,如何读取到 properties 配置文件中的内容?
(1)创建 jdbc.properties:
driverName = com.mysql.jdbc.Driverurl = jdbc:mysql://localhost:3306/myTest?useUnicode=true&characterEncoding=UTF-8user = rootpwd = 123456
(2)spring.xml 中配置 C3P0 数据源:
第一步,导入外部资源文件。
使用 context:property-placeholder 标签,需要导入 context 命名空间。
第二步,通过 ${} 表达式取出外部资源文件的值。
(3)在测试类中获取 Spring 创建的 DataSource 对象。
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");DataSource ds = (DataSource) applicationContext.getBean("dataSource");Connection conn = null;try { conn = ds.getConnection();} catch (SQLException e) { e.printStackTrace();}System.out.println(conn);
(4)运行代码,从运行结果可知,打印 DataSource 对象。
除了使用 \
直接通过代码来看。
(1)在 User 实体类中添加 Car 属性:
public class User { private int id; private String name; private int age; private Car car; public User() { System.out.println("创建了 User 对象"); } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", age=" + age + ", car=" + car + "]"; }}
(2)spring.xml 中创建 User bean 和 Car bean,并且通过 p 命名空间给属性赋值,同时完成依赖注入,注意需要引入 p 命名间:
(3)测试类中获取 User 对象,并打印:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User user = (User) applicationContext.getBean("user");System.out.println(user);
从运行结果可知,创建了 User 对象和 Car 对象,并且完成属性赋值以及级联关系。
点击了解《Spring MVC 实战手册》。
这节课讲解了 Spring IoC 两种常规操作,分别是依赖注入与 p 命名空间,依赖注入是维护对象关联关系的机制。p 命名空间实际上是对配置文件的简化,以提高我们的开发效率。
点击这里下载源码。
阅读全文: http://gitbook.cn/gitchat/column/5b86eb94ea7bc512755e4557