spring框架是springboot框架发展的基础,有必要熟悉下spring框架!!!
一、Spring框架
第一章、Spring基础
一、Spring发展历史
第一阶段:XML配置
Spring1.x时代
XML配置Bean,随着项目的扩大,我们需要把XML配置文件分放到不同的配置文件里
第二阶段:注解配置
Spring2.x时代
JDK1.5以后支持注解。例如:@Component、@Service。大大减少了配置量
最终的选择:应用基本配置使用XML,业务配置使用注解
第三阶段:Java配置
Spring3.x时代到现在
Spring提供了Java配置的能力,使用Java配置可以让你更理解你配置的Bean
Spring4.x和Spring Boot都推荐使用Java配置
二、Spring概述
Spring框架提供了IOC容器、AOP、数据访问、Web开发、消息、测试等相关技术的支持
Spring提供了一个IOC容器用来初始化对象,解决对象间的依赖管理和对象的使用
问:什么是Bean?
每一个被Spring管理的Java对象都称之为Bean
问:什么是pojo?
Plan Old Java Object,即无任何限制的普通Java对象
1、Spring的模块
Spring是模块化的,你可以只使用你需要的Spring的模块
1)核心容器 Core Container
- Spring-Core:核心工具类,Spring其他模块大量使用Spring-Core
- Spring-Beans:Spring定义Bean的支持
- Spring-Context:运行Spring的容器
- Spring-Context-Support:Spring容器对第三方包的集成支持
- Spring-Expression:使用表达式语言在运行时查询和操作对象
2)AOP
- Spring-AOP:基于代理的AOP支持
- Spring-Aspects:基于AspectJ的AOP支持
3)消息
- Spring-Messaging:对消息架构和协议的支持
4)Web
- Spring-Web:提供基础的Web集成的功能,在Web项目中提供Spring的容器
- Spring-Webmvc:提供基于Servlet的SpringMVC
- Spring-WebSocket:提供WebSocket功能
- Spring-Webmvc-Portlet:提供Portlet环境支持
5)数据访问/集成 Data Access/Integration
- Spring-JDBC:提供以JDBC访问数据库的支持
- Spring-TX:提供编程式和声明式的事务支持
- Spring-ORM:提供对对象/关系映射技术的支持
- Spring-OXM:提供对对象/xml映射技术的支持
- Spring-JMS:提供对JMS的支持
2、Spring的生态
- Spring Boot:使用默认开发配置来实现快速开发
- Spring XD:用来简化大数据应用开发
- Sprng Cloud:为分布式系统开发提供工具集
- Spring Data:对主流的关系型和NoSQL数据库的支持
- Spring Integration:通过消息机制对企业集成模式的支持
- Spring Batch:简化及优化大量数据的批处理操作
- Spring Security:通过认证和授权保护应用
- Spring Social:与社交网络API的集成
- Spring HATEOAS:基于HATEOAS原则简化REST服务开发
- Spring Mobile:提供对手机设备检测的功能,给不同的设备返回不同的页面支持
- Spring for Android:主要提供在Android上消费RESTful API的功能
- Spring Web Flow:基于Spring MVC提供基于向导流程式的Web应用开发
- Spring Web Services:提供了基于协议有限的SOAP/Web服务
- Spring LDAP:简化使用LDAP开发
- Spring Session:提供一个API及实现来管理用户会话信息
3、Spring基础配置
Spring框架的四大原则
- 使用pojo进行轻量级和最小侵入式开发
- 使用aop和模板减少模式化代码
- 通过aop和默认习惯实现声明式编程
- 通过依赖注入和接口编程实现松耦合
Spring所有功能的设计和实现都是基于此四大原则的
3.1、依赖注入
控制翻转和依赖注入在Spring环境下是等同的概念,控制翻转是通过依赖注入实现的。
概念:是指容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖
目的:主要是为了解耦,体现一种“组合”的理念
SpringIOC容器创建Bean,通过容器将功能类Bean注入到你需要的Bean中。
Spring提供了xml、注解、Java配置、groxy配置实现Bean的创建和注入。
称之为元数据(即描述数据的数据)
元数据本身不具备任何可执行的能力,只能通过外界代码来对这些元数据行解析后进行一些有意义的操作。
声明Bean的注解(标注在类上)
- @Component组件:没有明确的角色
- @Service:在业务逻辑层使用
- @Repository:在数据访问层使用
- @Controller:在展现层(MVC–Spring MVC)使用
注入Bean的注解(标注在属性或set方法上,一般都是标注属性上)
- @Autowired:Spring提供的注解
- @Inject:JSR-330提供的注解
- @Resource:JSR-250提供的注解
扫描包的注解
- @ComponentScan:自动扫描包名下所有使用@service、@Component等的类,并注册为Bean
3.2、Java配置
- @Configuration:声明当前类是一个配置类,相当于一个Spring配置的xml文件
- @Bean:注解在方法上,声明当前方法的返回值为一个Bean
何时使用Java配置或注解配置?
全局配置使用Java配置
业务Bean的配置使用注解配置:@Service、@Component、@Repository、@Controller
Spring容器提供的极好的功能
在Spring容器中,只要容器中存在某个Bean,就可以在另外一个Bean的声明方法的参数中注入
3.3、AOP
概念:面向切面编程
目的:是为了解耦,可以让一组类共享相同的行为
Spring支持AspectJ的注解式切面编程
- 使用**@Aspect**声明是一个切面
- 使用**@After**、@Before、@Around定义建言,可直接将拦截规则作为参数
- 其中@After**、@Before、@Around参数的拦截规则作为切点**(PointCut),为了使切点复用,可使用**@PointCut专门定义拦截规则**,然后在@After、@Before、@Around的参数值中调用
- 其中符合条件的每一个被拦截处为连接点(JoinPoint)
第二章、Spring常用配置
一、Bean的Scope
2.1、Scope概念
Scope描述的是Spring容器如何新建Bean的实例,是通过@Scope注解来实现
- Singleton:一个Spring容器中只会有一个Bean实例,是Spring的默认配置,全容器共享一个实例
- Prototype:每次调用新建一个Bean实例
- Request:Web项目中,给每一个http request新建一个Bean实例
- Session:Web项目中,给每一个http session新建一个Bean实例
- GlobalSession:这个只在portal应用中有用,给每一个global http session新建一个Bean实例
二、Spring EL和资源调用
2.2、Spring EL
概念:
Spring EL-Spring表达式语言,支持在xml和注解中使用表达式,类似于jsp的EL表达式
用途:
Spring开发中经常涉及调用各种资源的情况,包含普通文件、网址、配置文件、系统环境变量等
我们可以使用Spring的表达式语言实现资源的注入
用法:
Spring主要在注解@Value的参数中使用表达式
使用@PropertySource注解在类上,指明文件地址,然后@Value注入值
若使用@Value注入,还需要配置一个PropertySourcesPlaceholderConfigurer的Bean
三、Bean的初始化和销毁
2.3、Spring对Bean的生命周期的操作提供了支持
- Java配置方式:使用**@Bean的initMethod和destoryMethod**
- 注解方式:利用JSR-250的@PostConstruct和**@PreDestory**
四、Profile
2.4、Profile概念
Profile为在不同环境下使用不同的配置提供了支持
- 通过设定Environment的ActiveProfiles来设定当前context需要使用的配置环境。在开发中使用@Profile注解类或者方法,达到在不同情况下选择实例化不同的Bean。
- 通过设定jvm的spring.profiles.active参数来设置配置环境
- Web项目设置在Servlet的context parameter中
五、事件
2.5、事件概念
Spring的事件为Bean和Bean之间的消息通信提供了支持。当一个Bean处理完一个任务后,希望另外一个Bean知道并能做相应的处理,这时我们就需要让另外一个Bean监听当前Bean所发送的事件。
Spring事件遵守的流程
- 自定义事件,继承ApplicationEvent
- 定义事件监听器,实现ApplicationListener
- 使用容器发布事件
六、热部署
1、在pom文件中添加依赖
<!-- spring-boot-devtools热启动依赖包 start-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<!-- spring-boot-devtools热启动依赖包 end-->
2、左上角依次找到【File】——【Settings…】——【Build,Execution,Deployment】——【Compiler】
勾选"Build project automatically",然后右下角【Apply】——【OK】
3、使用 Ctrl+Shift+A 快捷键搜索"Registry",选择搜索出来的第一个:
4、找到"compiler.automake.allow.when.app.running",勾选,【Close】关闭:
5、重启项目,完事~
第三章、Spring高级话题
一、Spring Aware
概念
在实际项目中,你不可避免的要用到Spring容器本身的资源,这时你的Bean必须要意识到Spring容器的存在,才能调用Spring所提供的资源,这就是所谓的Spring Aware
目的
是为了让Bean获得容器的服务
Spring提供的Aware接口
- BeanNameAware:获得到容器中Bean的名称
- BeanfactoryAware:获得当前Bean factory,这样可以调用容器的服务
- ApplicationContextAware*:当前的Application context,这样可以电影容器的服务
- MessageSourceAware:获得message source,这样可以获得文本信息
- ApplicationEventPublisherAware:应用事件发布器,可以发布事件
- ResourceLoaderAware:获得资源加载器,可以获得外部资源文件
二、多线程
Spring多线程
Spring通过任务执行器来实现多线程和并发编程。
使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor。
实际开发中任务一般是非阻碍的,即异步的,所以要在配置类中通过**@EnableAsync开启对异步任务的支持**,并通过在实际执行的Bean的方法中使用**@Async**注解来声明其是一个异步任务。
@Async如果注解在方法上,表明该类所有的方法都是异步方法。
三、计划任务
-
首先通过在配置类注解@EnableScheduling来开启对计划任务的支持
-
然后在要执行计划任务的方法上注解@Scheduled来声明这是一个计划任务
spring通过@Scheduled支持多种类型的计划任务,包含cron、fixDelay、fixRate等
四、条件注解@Conditional
通过活动的profile,我们可以获得不同的Bean
Spring4提供了更通用的基于条件的Bean的创建,即使用@Conditional
@conditional根据满足某一个特定条件创建一个特定的Bean
五、 组合注解和元注解
元注解概念
元注解其实就是可以注解到别的注解的注解
组合注解概念
就是被注解的注解称之为组合注解,组合注解具备元注解的功能
六、@Enable*注解的工作原理
观察@Enable*注解的源码,发现所有的注解都有一个@Import注解,@Import是用来导入配置类的,者也就意味着这些自动开启的实现其实是导入了一些自动配置的Bean
- 直接导入配置类,例如:@EnableScheduling
- 依据条件选择配置类,例如:@EnableAsync
- 动态注册Bean,例如:@EnableAspectJAutoProxy
七、测试
单元测试只针对当前开发的类和方法进行测试
集成测试能够知道系统的各个部分组合在一起是否能正常工作
Spring通过Spring TestContext Framework对集成测试提供顶级支持。它不依赖于特定的测试框架,即可使用Junit,也可使用TestNG。
第四章、SpringMVC基础
一、SpringMVC概述
什么是MVC?
Model+View+Controller(数据模型+视图页面+控制器)
SpringMVC可以简单地开发灵活且松耦合的Web项目,和Spirng框架零配置结合
什么是三层架构?
Presentation tier+Application tier+Data tier(展现层+应用层+数据访问层)
三层架构是整个应用框架,是由Spring框架负责管理的
MVC和三层架构的关系?
MVC只存在于展现层
二、SpringMVC项目快速搭建
SpringMVC的ViewResolver,这是SpringMVC视图渲染的核心机制
SpringMVC里有个接口叫做ViewResolver,实现这个接口要重写方法resolveViewName( ),这个方法的返回值是接口View,而View的职责就是使用model、request、response对象,并将渲染的视图返回给浏览器。
三、SpringMVC常用注解
- @Controller:注解在类上,表明该类是SpringMVC里的Controller(控制类),并将其声明为Spring的一个Bean,Dispatcher Servlet会自动扫描注解了此类的类,并将Web请求映射到注解了@RequestMapping的方法上。
- @RequestMapping:注解在类或方法上,用来映射Web请求(访问路径和参数)、处理类和方法的。注解在方法上的@RequestMapping路径会继承注解在类上的路径。
- @ResponseBody:注解可放置在返回值前或者方法上,将返回值放在response体内,而不是返回一个页面。在很多基于ajax的程序的时候,可以以此注解返回数据而不是页面。
- RequestBody:注解放置在参数前,@RequestBody允许requeste的参数在request体中,而不是在直接链接在地址后面。
- PathVariable:注解放置在参数前,用来接收路劲参数,如/news/001,可接收001作为参数
- @RestController:注解在类上,是一个组合注解,组合了@Controller和@ResponseBody,当你只开发一个和页面交互数据的控制的时候,使用此注解
四、SpringMVC基本配置
4.1、静态资源映射
静态资源需要直接访问,可以在配置里重写addResourceHandler方法来实现
4.2、拦截器配置
可以让普通Bean实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter类来实现自定义拦截器
通过重写WebMvcConfigurerAdapter的addInterceptors方法来注册自定义的拦截器
重写preHandler方法,在请求发生前执行
重写postHandler方法,在请求完成后执行
配置拦截器的Bean
重写addInterceptors方法,注册拦截器
4.3、@ControllerAdvice
通过@ControllerAdvice,我们可以将对于控制器的全局配置放置在同一个位置
注解了@Controller的类的方法可以使用**@ExceptionHandler**、@InitBinder、@ModelAttribute注解到方法上,这对所有注解了@RequestMapping的控制器内的方法有效
- @ExceptionHandler:用于全局处理控制器里的异常,value属性可过滤拦截条件
- @InitBinder:用来设置WebDataBinder,WebDataBinder是用来自动绑定前台请求参数到Model中
- @ModelAttribute:本来的作用是绑定键值对到Model里,这里是让全局的@RequestMapping都能获得在此处设置的键值对
4.4、其他配置
- 快捷的ViewController:在开发中涉及到的大量的页面转向,可以通过在配置中重写addViewConreollers拉力简化配置。
- 路径匹配参数设置:路劲参数如果带 . 的话, . 后面的值将会被忽略,通过重写configurePathMatch方法不忽略 . 后面的参数。
- 跟多配置请查看WebMvcConfigurerAdapter类的API、
五、SpringMVC的高级配置
5.1、文件上传
SpringMVC通过配置一个MultipartResolver来上传文件
通过MultipartFile file来接收文件,通过MultipartFile[ ] files接收多个文件上传
5.2、自定义HttpMessageConverter
HttpMessageConverter是用来处理request和response里的数据的。
Spring为我们内置了大量的HttpMessageConverter。
5.3、服务器端推送技术
六、SpringMVC的测试
第五章、SpringBoot基础
一、SpringBoot概述
1.1、Spring的核心功能
- 独立运行Spring项目:可以以独立的jar包形式运行
- 内嵌Servlet容器:可以选择内嵌Tomcat、Jetty或者Undertow,这样无需war包形式部署
- 准生产的应用监控:提供基于http、ssh、telnet对运行时的项目进行监控
- 提供starter简化Maven配置:提供一系列的starter pom来简化Maven的依赖加载
- 自动配置Spring:会根据在类路径中的jar包、类、为jar包里的类自动配置Bean
- 无代码生成和xml配置:通过条件注解来实现,这是Spring4.x提供的新特性
1.2、SpringBoot的优缺点
优点
- 快速构建项目
- 对主流开发框架的无配置集成
- 项目可独立运行,无需依赖外部的Servlet容器
- 提供运行时的应用监控
- 极大的提高了开发、部署效率
- 与云计算的天然集成
缺点
- 书籍稳定较少且不够深入
- 如果你不认同Spring框架,这也许算是它的缺点。
二、SpringBoot快速搭建
第六章、SpringBoot核心
6.1、基本配置
1、入口类和@SpringBootApplication
SprinBoot通常有一个名为Application的入口类*,入口类里有一个main方法,这是标准的Java应用入口方法
@SpringBootApplication是SpringBoot的核心注解类,它是一个组合注解
@SpringBootApplication//核心注解类
public class Ch523Application {//入口类
//标准的java应用入口方法
public static void main(String[] args) {
SpringApplication.run(Ch523Application.class, args);
}
}
@SpringBootApplication注解源码上的注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration//主要的注解之一
@EnableAutoConfiguration//主要的注解之一
@ComponentScan//主要的注解之一
若不使用@SpringBootApplication注解,则需要在入口类上直接使用:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
2、关闭特定的自动配置
关闭特定的自动配置应该使用@SpringBootApplication注解的exclude参数
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
3、定制Banner
1)、修改Banner
在SpringBoot启动时会有一个默认启动图案
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.6.RELEASE)
在src/main/resources下新建一个banner.txt
通过http://patorjk.com/software.taag网站生成字符,将生成的字符复制到banner.txt中
再次启动程序,图案将会发生变化
2)、关闭Banner
main里的内容修改为:
SpringApplication app = new SpringApplication(Ch523Application.class);
app.setShowBanner(false);
app.run(args);
或者使用fluent API修改为:
new SpringApplicationBuilder(Ch523Application.class)
.showBanner(false)
.run(args);
4、SpringBoot的配置文件
支持properties配置文件,支持yaml语言的配置文件
SpringBoot使用一个全局的配置文件application.properties或则application.yml
放置在src/main/resources目录或者类路径/config下
什么是yaml?
yaml是以数据为中心的语言,在配置数据的时候具有面向对象的特征
在src/main/resources目录下若两种配置文件同时存在,则properties配置文件优先
5、starter pom
只要使用场景所需要的starter pom,相关的技术配置将会消除,就可以得到SpringBoot为我们提供额自动配置的Bean
6、使用xml配置
SpringBoot提倡零配置,即无xml配置,但是在实际项目中,可能有一些特殊要求你必须使用xml配置,这时我们可以通过Spring提供的@ImportResource来加载xml配置
@ImportResource({"classpath:some-context.xml","classpath:another-context.xml"})
6.2、外部配置
1、命令行参数配置
SpringBoot是可以基于jar包运行的,打成jar包的程序可以通过如下命令运行
java -jar xx.jar
或者通过命令修改Tomcat端口号
java -jar xx.jar --server.port=9090
2、常规属性配置
在常规Spring环境下,注入properties文件里的值的方式:
@PropertySource指明properties文件的位置,然后通过@Value注入值
在SpringBoot环境下的操作:
在application.properties文件里定义属性,然后直接使用@Value注入即可
3、类型安全的配置(基于properties)
SpringBoot还提供了基于类型安全的配置方式,通过**@ConfigurationProperties将properties属性和一个Bean基于属性**关联,从而实现类型安全的配置
6.3、日志配置
SpringBoot支持Java Util Logging、Log4j、Log4j2和Logback作为日志框架
无论使用哪种,SpringBoot一位当前使用日志空间的控制台输出及文件输出做好了配置。
默认情况下,SpringBoot使用Logback作为日志框架
配置日志文件:
logging.file = D:/mylog/log.log
配置日志级别,格式为logging.level.包名=级别
logging.level.org.springframework.web = DEBUG
6.4、Profile配置
Profile是Spring用来针对不同的环境对不同的配置提供支持的
全局Profile配置使用application-{profile}.properties。例如:application-prod.properties
通过在application.properties中设置spring.profiles.active=prod来指定活动的Profile
6.5、SpringBoot运行原理
SpringBoot关于自动配置的源码位于org.springframework.boot:spring-boot:2.1.1RELEASE下
三种方式查看当前项目中已启用和未启用的自动配置的报告
- 运行jar是增加 –debug 参数
java -jar xx.jar --debug
- 在application.properties配置文件中设置属性
debug = true
- 在STS中设置
书P152看图
1、运作原理
首先看**@SpringBootApplication**注解
这是一个组合注解,他的核心功能是由**@EnableAutoConfiguration**注解提供
@EnableAutoConfiguration源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})//关键功能
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
这里的关键功能是**@Import注解导入的配置功能**
AutoConfigurationImportSelector使用SpringFactoriesLoader.loadFactoryNames方法
来扫描具有META-INF/spring.factories文件的jar包
而org.springframework.boot:spring-boot:2.1.1RELEASE里就有一个spring.factories文件
此文件声明了有哪些自动配置。
第七章、SpringBoot的Web开发
7.1、SpringBoot的Web开发支持
SpringBoot提供了spring-boot-starter-web为Web开发予以支持
spring-boot-starter-web提供了嵌入的Tomcat以及SpringMVC的依赖
Web相关的自动配置存储在spring-boot-autoconfigure.jar的org.springframework.boot.autoconfigure.web下
7.2、Thymeleaf模板引擎
SpringBoot推荐使用Thymeleaf模板引擎,因为Thymeleaf提供了完美的SpringMVC的支持
为什么不用jsp?
因为jsp在内嵌的Servlet容器上运行有问题,内嵌的容器不支持以jar的形式运行jsp,Undertow不支持jsp
1、Thymeleaf基础知识
Thymeleaf是一个Java类库,是一个xml/xhtml/html5模板引擎,可以作为MVC的Web应用View层
还提供额外的模块与SpringMVC集成,所以可以完全替代jsp
- 引入Thymeleaf
<html xmlns:th="http://www.thymeleaf.org">
</html>
- **@{ } **引入静态资源
<link th:src="@{bootstrap/css/bootstrap.min.css}" rel="stylesheet"/>
- ${ } 访问model中数据
<span th:text="${singlePerson.name}"></span>
- **th:each **数据迭代
<!--people 是model中存在的集合,所以用 ${} 获取-->
<li th:each="person:${people}">
<!--person 自己定义的,代表每次迭代的对象-->
<span th:text="person.name"></span>
<span th:text="person.age"></span>
</li>
- th:if 数据判断
<div th:if="${not #lists.isEmpty(people)}">
<!-- 判断people集合是否为空 -->
</div>
<!--
Thymeleaf支持>,<,>=,<=,!=,==作为比较条件
同时也支持将SpringEL表达式语言用于条件中
-->
- th:inline 在JavaScript中访问model
- [ [ ${ } ] ] 格式获得实际的值
<script th:inline="javascript">
//让JavaScript代码能够访问model中的属性
var single=[[${ singlePerson }]]
</script>
- th:onclick 绑定点击事件
<button th:onclick="'getName(\"+${person.name}+'\')'">获得名字</button>
7.3、Web相关配置
通过查看WebMvcAutoConfiguration和WebMvcProperties的源码
1、SpringBoot提供了如下的自动配置
1)、自动配置的ViewResolver
- ContentNegotiatingViewResolver:是SpringMVC提供的一个特殊的ViewResolver,它不是自己处理View,而是代理给不同的ViewResolver来处理不同的View,所以它有最高的优先级。
- BeanNameViewResolver:在控制器中的一个方法的返回值的字符串(视图名)会根据BeanNameViewResolver去查找Bean的名称为返回字符串的View来渲染视图。
- InternalResourceViewResolver:这是一个极为常用的ViewResolver,主要通过设置前缀、后缀,以及控制器中的方法来返回视图名的字符串,以得到实际的页面
2)、自动配置的静态资源
在自动配置类的addResourceHandlers方法中定义了以下静态资源的自动配置
-
类路径文件
把类路劲下的/static、/public、/resources和META-INF/resources文件夹下的静态文件直接映射为 /**
可以通过http://localhost:8080/**来访问
-
webjar
webjar就是将我们常用的脚本框架封装在jar包中的jar包
把webjar的/META-INF/resources/webjars/下的静态文件映射为/webjar/**
可以通过http://localhost:8080/webjar/**来访问
3)、自动配置的Formatter和Converter
只要我们定义了Converter、GenericConverter和Formatter接口的实现类的Bean
这些Bean就会自动注册到SpringMVC中。
4)、自动配置的HttpMessageConverters
如果要新增自定义的HttpMessageConverter
只需要定义一个你自己的HttpMessageConverters的Bean
然后在此Bean中注册自定义HttpMessageConverter即可
5)、静态首页的支持
把静态index.html文件放置在如下目录(任意即可)
- classpath:/META-INF/resources/index.html
- classpath:/resources/index.html
- classpath:/static/index.html
- classpath:/public/index.html
访问http://localhost:8080/时,会直接映射
2、接管SpringBoot的Web配置
在SpringBoot提供SpringMVC默认配置不符合你的需求时,则可以通过一个配置类(注解有@Configuration的类)加上@EnableWebMvc注解来实现完全自己控制的MVC配置
在既要保留SpringBoot的默认MVC配置,又需要增加自己的额外的配置的时候,可以定义一个配置类并继承WebMvcConfigurerAdapter,无需使用@EnableWebMvc注解,然后按照SpringMVC的配置方法来添加SpringBoot为我们所做的其他配置
3、注册Servlet、Filter、Listener
当使用嵌入式的Servlet容器时,通过将Servlet、Filter、和Listener声明为Spring Bean而达到注册的效果
或者注册ServletRegistrationBean、FilterRegistrationBean和ServletListenerRegistrationBean的Bean
4、Tomcat配置
1)、配置Tomcat
Tomcat的所有属性都在org.springframework.boot.autoconfigure.web.ServerProperties配置类中做了定义
我们只需要在application.properties文件里配置属性做配置即可
容器配置都已servlet作为前缀,Tomcat特有配置都以servlet.tomcat作为前缀
# 配置Servlet容器
# 配置端口号,默认为8080
server.port=8090
# 用户会话session的过期时间,秒为单位
server.servlet.session.timeout=30
# 配置访问路径,默认为/
server.servlet.context-path=/hello
# 配置Tomcat编码,默认为utf-8
server.tomcat.uri-encoding=utf-8
# 配置Tomcat是否开启压缩,默认为关闭off
server.tomcat.compression=off
2)、代码配置Tomcat
如果需要通过代码的方式配置servlet容器,则可以注册一个实现EmbeddedServletContainerCustomizer接口的Bean
若想直接配置Tomcat、Jetty、Undertow,则可以直接定义TomcatEmbeddedServletContainerFactory、JettyEmbeddedServletContainerFactory、UndertowEmbeddedServletContainerFactory
3)、替换Tomcat
SpringBoot默认使用Tomcat
替换为Jetty:
在ppm.xml中,将spring-boot-starter-web的依赖
由spring-boot-starter-tomcat修改为spring-boot-starter-Jetty
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<!--重点是这里-->
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
替换为Undertow:
在ppm.xml中,将spring-boot-starter-web的依赖
由spring-boot-starter-tomcat修改为spring-boot-starter-Undertow
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<!--重点是这里-->
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
4)、SSL配置
SSL(Secure Sockets Layer,安全套接层)是位网络通信提供安全及数据完整性的一种安全协议,SSL在网络传输层对网络连接进行加密
SSL协议位于TCP/IP协议与各种应用层协议之间,为数据提供安全支持。
SSL协议分为两层:
- SSL记录协议(Secure Socket Layer):它建立在可靠的传输协议之上,为高层协议提供数据封装、压缩、加密等基本功能的支持
- SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际数据传输开始前,通信双方进行身份验证、协商加密算法、交换加密秘钥等。
在基于B/S的Web应用中,是通过HTTPS来实现SSL的。
在HTTP下加入SSL层,HTTPS的安全基础是SSL。
http拓展
HTTPS是以安全为目标的http通道,是http的安全版本。
1、生成证书
书P193
2、SpringBoot配置SSL
将.keystore文件复制到整个项目的根目录下(不是src,是更外面一层的)
然后在application.properties做如下配置
server.port = 8443
server.ssl.key-store = .keystore
server.ssl.key-store-password = 123456
server.ssl.key-store-type = JKS
server.ssl.key-alias = tomcat
启动SpringBoot项目,并访问https://localhost:8443
3、http转向https
需要配置TomcatEmbeddedServletContainerFactory,并且添加Tomcat的connector来实现
书P195
完成后,访问http://localhost:8080/即可跳转到https://localhost:8443
7.5、Favicon配置
1、默认的Favicon
SpringBoot已经提供了默认的Favicon,每次访问都能看见
2、关闭Favicon
在application.properties中设置关闭Favicon,默认为开启
spring.mvc.favicon.enabled = false
3、设置自己的Favicon
将自己的favicon.ico(文件名是固定的)文件放置在
- 类路径根目录下
- 类路径META-INF/resources/下
- 类路径resources/下
- 类路径static/下
- 类路径public/下
即可使用自己的favicon.ico
7.6、WebSocket
1、什么是WebSocket
WebSocket为浏览器和服务端提供了双工异步通信的功能,即双向通信。WebSocket需要浏览器的支持
WebSocket是通过一个socket来实现双工异步通信能力的
我们使用它的子协议STOMP,它是一个更高级的协议
STOMP协议使用一个基于帧(frame)的格式来定义消息
类似于request和response(类似于@RequestMapping的@MessageMapping)
2、SpringBoot提供的自动配置
SpringBoot为WebSocket提供的stater pom是spring-boot-starter-websocket
3、实战
广播式:服务端有消息时,会将消息发送给所有连接当前endpoint的浏览器
点对点式
7.7、基于Bootstrap和AngularJS的现代Web应用
现代B/S系统特色:
- 单页面应用
- 响应式设计
- 数据导向
1、Bootstrap
Boostrap是开发响应式和移动优先的Web应用
2、AngularJS
第八章、SpringBoot的数据访问
SpringBoot Data是一个伞形项目,包含了大量的关系型数据库和非关系型数据库的数据访问解决方案
SpringData为我们使用统一的API来对上述的数据存储技术进行数据访问操作提供了支持
Spring Data Commons使用基于Spring统一标准CRUD(创建、获取、更新、删除)
查询、排序、分页的相关操作
Spring Data Commons的一个重要概念:Spring Data Repository抽象。使用Spring Data Repository可以极大的减少数据访问层的代码。
Spring Data可以根据属性名进行计数、删除、查询方法等操作
8.1、引入Docker
8.2、Spring Data JPA
8.2.1、认识Spring Data JPA
1、什么是Spring Data JPA?
首先认识Hibernate:Hibernate使用O/R映射(Object-Relational Mapping)技术实现数据访问。
O/R映射即将领域模型和数据库的表进行映射,通过程序操作对象而实现表数据操作的能力,让数据访问操作无需关注数据库相关的技术。
JPA即Java Persistence API。是一个基于O/R映射的标准规范。
JPA的主要实现由Hibernate、EclipseLink、OpenJPA等。
Spring Data JPA是Spring Data的一个子项目。它通过提供基于JPA的Repository极大的减少了JPA作为数据访问方案的代码量。
2、定义数据访问层
使用Spring Data JPA建立数据访问层,只需定义一个继承JpaRepository的接口
public interface PersonRepository extends JpaRepository<Person,long>{
//定义数据访问操作的方法
}
3、配置使用Spring Data JPA
在Spring环境中,通过**@EnableJpaRepositories注解**开启Spring Data JPA的支持
@EnableJpaRepositories接收的value参数用来扫描数据访问层所在包下的数据访问的接口定义
4、定义查询方法
(1)根据属性名查询
Spring Data JPA支持通过定义在Repository接口中的方法名来定义查询,而方法名是根据实体类的属性名来确定的
1)常规查询
//通过名字相等查询,参数为name
//相当于JPQL:select p from Person p where p.name=?
List<Person> findByName(String name);
//通过名字like查询,参数为name
//相当于JPQL:select p from Person p where p.name like ?
List<Person> findByNameLike(String name);
//通过名字和地址查询,参数为name和address
//相当于JPQL:select p from Person p where p.name=? and p.address=?
List<Person> findByNameAndAddress(String name,String address);
查询关键字
关键字 | 示例 | 同功能 |
---|---|---|
And | FindByLastnameAndFirstname | where x.lastname=? and firstname=? |
Or | FindByLastnameOrFirstname | |
Is,Equals | FindByFirstname,fingByFirstnameIs, findByFirstnameEquals | |
Between | ||
LessThan | ||
LessThanEqual | ||
GreaterThan | ||
GreaterThanEqual | ||
After | ||
Before | ||
IsNull | ||
IsNotNull,NotNull | ||
Like | ||
NotLike | ||
StartingWith | ||
EndingWith | ||
Containing | ||
OrderBy | ||
Not | ||
In | ||
NotIn | ||
True | findByActiveTrue( ) | |
False | findByActiveFalse( ) | |
IgnoreCase | findByFirstnameIgnoreCase |
2)限制结果数量
结果数量是用 top 和或 first 关键字来实现的
//获得符合查询条件的前10条数据
List<Person> findFirst10ByName(String name);
//获得符合查询条件的前30条数据
List<Person> findTop30ByName(String name);
(2)使用JPA的@NamedQuery查询
支持用JPA的**@NamedQuery来定义查询方法**,即一个名称映射一个查询语句
@Entity
@NamedQuery(name = "Person.findByName"),query="select p from Person p where p.name=?"
public class Person{
}
使用如下语句
public interface PersonRepository extends JpaRepository<Person,Long>{
//使用的是NamedQuery里定义的查询语句,而不是根据方法名称查询
List<Person> findByName(String name);
}
(3)使用@Query查询
1)使用参数索引
JPA支持用**@Query注解在接口的方法上**实现查询
public interface PersonRepository extends JpaRepository<Person,Long>{
@Query("select p from Person p where p.address=?")
List<Person> findByAddress(String address);
}
2)使用命名参数
JPA支持在语句里用名称来匹配查询参数
public interface PersonRepository extends JpaRepository<Person,Long>{
@Query("select p from Person p where p.address=:address")
List<Person> findByAddress(@Param("address")String address);
}
3)更新查询
JPA支持 @Modifying 和 @Query 注解组合来事件更新查询
public interface PersonRepository extends JpaRepository<Person,Long>{
@Modifying
@Transactional
@Query("update Person p set p.name=?")
int setName(String name);
//返回值int表示更新语句影响的行数
}
(4)Specification
JPA提供了基于准则查询的方式,即Criteria查询
而Spring Data JPA提供了一个Specification接口构造准则查询,Specification接口定义了一个toPredicate方法用来构造查询条件
1)定义
//接口类必须实现JpaSpecificationExexutor接口
public interface PersonRepository extends JpaRepository<Person,Long>,JpaSpecificationExexutor<Person>{
}
//然后需要定义Criterial查询
public class CustomerSpecs{
//查出所有来自苏州的人
public static Specification<Person> personFromSuzhou(){
return new Specification<Person>(){
@Override//通过root获得需要查询的属性,通过CriteriaBuilder构造查询条件
public Predicate toPredicate(Root<Person> root,CriteriaQuery<?> query,CriteriaBuilder cb){
return cb.equal(root.get("address"),"苏州");
}
};
}
//Predicate、Root、CriteriaQuery、CriteriaBuilder都是来自JPA的接口
}
2)使用
//静态导入
import static com.wisely specs.CustomerSpecs.*;
//注入personRepository的Bean后
List<Person> people=personRepository.findAll(personFromSuzhou);
(5)排序和分页
JPA充分考虑在实际开发中所必须的排序和分页场景,提供了Sort类、Page接口和Pageable接口
1)定义
public interface PersonRepository extends JpaRepository<Person,Long>{
List<Person> findByName(String name,Sort sort);
Page<Person> findByName(String name,Pageable pageable);
}
2)使用排序
List<Person> people=personRepository.findByName("xx",new Sort(Direction.ASC,"age"));
3)使用分页
List<Person> people=personRepository.findByName("xx",new PageRequest(0,10));
//其中page接口还可以获得当前页面的记录、总页数、总记录数、是否有上一页或下一页等
5、自定义Repositor的实现
(1)定义自定义Repository接口
@NoRepositoryBean//此注解指明当前这个接口不是我们领域类的接口(例如Repository)
public interface CustomRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>{
//我们自定义的Repository实现PagingAndSortingRepository具备排序和分页的能力
public void doSomething(ID id);//要定义的数据操作方法在接口中定义
}
(2)定义接口实现
public class CustomRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CustomRepository<T, ID>{
//首先实现CustomRepository接口,继承SimpleJpaRepository类让我们可以使用其提供的方法(如findAll)
private final EntityManager entityManager;//让数据操作方法中可以使用entityManager
public CustomRepositoryImpl<Class<T> domainClass,EntityManager entityManager>{
//有参构造函数
this.entityManager = entityManager;
}
public void doSomething(ID id){
//定义数据访问操作,如调用findAll方法并构造一些查询条件
}
}
(3)自定义RepositoryFactoryBean
(4)开启自定义支持使用@EnableJpaRepository的repositoryFactoryBeanClass来指定FactoryBean即可
@EnableJpaRepository(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)