Java SSM框架
Spring
Spring Framework系统架构
Spring Framework是Spring生态圈中最基础的项目,是其他项目的根基
Spring核心
代码书写现状:耦合性偏高
解决方案:使用对象时,在程序中不要注定使用new产生对象,转换为由外部提供对象
IoC(Inversion of Control)控制反转
使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象的创建控制权由程序转移到外部,这种思想称为控制反转
Spring技术对IOC思想进行了实现:Spring提供了一个容器,称为IoC容器(系统架构中的Core Container),用来充当IoC思想的“外部”。
IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中被称为Bean
DI (Dependency Injection) 依赖注入
在容器中建立Bena与Bean之间的依赖关系的整个过程,称为依赖注入
目标:充分解耦
- 使用IoC容器管理bean (IoC)
- 在IoC容器内将有依赖关系的bean进行绑定 (DI)
最终效果:使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系
Bean实例化方式
- 无参构造实例化bean
- 静态工厂实例化bean
- 实例工厂实例化bean
- FactoryBean实例化bean
Bean的生命周期
生命周期:从创建到消亡的完整过程
Bean生命周期:bean从创建到销毁的整体过程(对象从创建到销毁)
Bean生命周期控制:在bean创建后到销毁前做一些事情
1、bean生命周期控制:
配置
init-method
destory-method
接口
InitializingBean
DisposableBean
2、关闭容器:
ConfigurableApplicationContext
close()
registerShutdownHook()
依赖注入
向一个类中传递数据的方式:
- 普通方法(set方法)
- 构造方法
创建Bean依赖的数据类型:
- 引用类型
- 简单类型(基本数据类型与String)
依赖注入方式:
setter注入
简单类型
引用类型
构造器注入
简单类型
引用类型
依赖注入方式选择:
- 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
- 可选依赖使用setter注入进行,灵活性强
- Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
- 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
- 实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
- 自己开发的模块推荐使用setter注入
依赖自动装配:
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
自动装配方式:
- 按类型(常用)
- 按名称
- 按构造方法
- 不启用自动装配
依赖自动装配特征:
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作
- 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
- 自动装配优先级低于setter注入与构造器注入,同时出现自动装配配置失效
容器
创建容器:
- ClassPathXmlApplicationContext
- FileSystemXmlApplicationContext
获取bean:
- 获取之后强转
- 获取时添加获取的类型参数
- 按照类型获取
注解开发
注解开发定义bean
//加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class)
@Configuration注解用于设定当前类为配置类
@ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式
Spring提供@Componemt注解的三个衍生注解
- @Controller:用于表现层bean定义
- @Service:用于业务层bean定义
- @Repository:用于数据层bean定义
@Autowired注解用于自动装配类型
@Value注解用于设定简单类型的值
@PropertySource注解加载properties文件
AOP(Aspect Oriented Programming)面向切面编程
一种编程范式,指导开发者如何组织程序结构–(OOP(Object Oriented Programming)面向对象编程)
作用:在不惊动原始设计的基础上为其进行功能增强
Spring理念:无入侵式/无侵入式
核心概念
- 连接点(JoinPoint):程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等
在SpringAOP中,理解为方法的执行 - 切入点(PointCut):要进行功能增强的方法
切入点表达式:匹配连接点的式子
在SpringAOP中,一个切入点表达式可以只描述一个具体方法,也可以匹配多个方法
一个具体方法:com.itheima.dao包下的BookDao接口中的无形参无返回值的save方法
匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法 - 通知(Advice):在切入点处执行的操作,也就是共性功能
在SpringAOP中,功能最终以方法的形式呈现 - 通知类:定义通知的类
- 切面(Aspect):描述通知与切入点的对应关系
工作流程
Spring容器启动
读取所有切面配置中的切入点
初始化bean,判定bean对应的类中的方法是否匹配到任意切入点
匹配失败,创建对象
匹配成功,创建原始对象(目标对象)的代理对象
获取bean执行方法
获取bean,调用方法并执行,完成操作
获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作
目标对象(Target):原始功能去掉共性功能对应的类产生的对象,这种对象是无法直接完成最终工作的
代理(Proxy):目标对象无法直接完成的工作,需要对其进行功能回填,通过原始对象的代理对象实现
SpringAOP本质:代理模式
切入点表达式
切入点表达式标准格式:动作关键字(访问修饰符 返回值 包名.类/接口名.方法名(参数) 异常名)
Execution (public User com.itheima.service.UserService.findById(int))
- 动作关键字:描述切入点的行为动作,例如execution表示执行到指定切入点
- 可以使用通配符描述切入点,快速描述
通知获取数据
获取切入点方法的参数
JoinPoint:适用于前置、后置、返回后、抛出异常后通知
ProceedJoinPoint:适用于环绕通知
获取切入点方法返回值
返回后通知
环绕通知
获取切入点方法运行异常信息
抛出异常后通知
环绕通知
Spring事务
事务简介
Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败
开启事务步骤:
- 在业务层接口上添加Spring事务管理
- 设置事务管理器
- 开启注解式事务驱动
注意事项:Spring注解式事务通常添加在业务层接口中而不会添加到业务层实现类中,降低耦合。注解式事务可以添加到业务方法上表示当前方法开启事务,也可以添加到接口上表示当前接口所有方法开启事务。
事务角色
- 事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法
- 事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法
事务属性
SpringMVC
SpringMVC简介
概述
SpringMVC技术与Servlet技术功能等同,均属于web层开发技术
SpringMVC是一种表现层框架技术,用于表现层功能开发
SpringMVC是一种基于Javahi实现MVC模型的轻量级WEB框架
优点
- 使用简单,开发便捷
- 灵活性强
入门案例
名称:@Controller
类型:类注解
位置:SpringMVC控制器类定义上方
作用:设定SpringMVC的核心控制器bean
范例:
@Controller
public class UserController{
}
名称:@ResponseBody
类型:方法注解
位置:SpringMVC控制器方法定义上方
作用:设置当前控制器方法响应内容为当前返回值,无需解析
范例:
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'info':'springmvc'}";
}
SpringMVC入门程序开发总结(1+N)
1次工作:
- 创建工程,设置服务器,加载工程
- 导入坐标
- 创建Web容器启动类,加载SpringMVC配置,并设置SpringMVC请求拦截路径
- SpringMVC核心配置类(设置配置类,扫描controller包,加载Controller控制器bean)
N次工作:
- 定义处理请求的控制器类
- 定义处理请求的控制器方法,并配置映射路径(@RequestMapping)与返回json数据(@ResponseBody)
入门案例工作流程分析
启动服务器初始化过程:
服务器启动,执行ServletContainerInitConfig类,初始化web容器
执行createServletApplicationContext方法,创建了WebApplicationContext对象
加载SpringMvcConfig
执行@ComponentScan加载对应的bean
加载UserController,每个@RequestMapping的名称对应一个具体的方法
执行getServletMapping方法,定义所有的请求都通过SpringMVC
单次请求过程:
- 发送请求localhost/save
- web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理
- 解析请求路径/save
- 由/save匹配执行对应的方法save()
- 执行save()
- 检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方
Bean加载控制
Controller加载控制与业务bean加载控制:(加载属于自己的bean)
SpringMVC相关bean(表现层bean)
Spring控制的bean:
- 业务bean(Service)
- 功能bean(DataSource等)
SpringMVC相关bean加载控制:
- SpringMVC加载的bean对应的包均在com.itheima.controller包内
Spring相关bean加载控制:
- 方式一:Spring加载的bena设定扫描范围为com.itheima,排除掉controller包内的bean
- 方式二:Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等
- 方式三:不区分Spring和SpringMVC的环境,加载到同一个环境中
名称:@ComponentScan
类型:类注解
范例:
@Configuration
@ComponentScan(value = "com.itheima",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig{
}
属性:
- excludeFilters:排除扫描路径中加载的bean,需要指定类别(type)与具体项(classes)
- includeFilters:加载指定的bean,需要指定类别(type)与具体项(classes)
请求与响应
请求映射路径
名称:@RequestMapping
类型:方法注解 类注解
位置:SpringMVC控制器方法定义上方
作用:设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀
范例:
@Controller
@RequestMapping("/user")
public class UserController{
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
}
属性:
- value(默认):请求访问路径,或访问路径前缀
请求方式
Get请求
Post请求
SpringMVC中需要解决Post请求中文乱码问题
请求参数
普通参数
普通参数:请求参数名与形参变量名不同,使用@RequestParam绑定参数关系
(@RequestParam(“”name) Strign userName, int age)
POJO参数:请求参数名与形参对象属性名相同,定义POJO类型参即可接收参数
(User user)
嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数
(User user)
数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型形参即可接收参数
(String[] likes)
集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系
(@RequestParam List
JSON数据参数
发送数据
开启自动转换json数据的支持(在SpringMvcConfig中)
@EnableWebMvc设置接收数据
JSON数据参数:(@RequestBody List
likes)–发送数据如上图 POJO参数:json数据与形参对象属性名相同,定义POJO类型形参即可接收参数
(@RequestBody User user)POJO集合参数:json数组数据与集合泛型 属性名形同,定义List类型形参即可接收参数
(@RequestBody Listlist)
比较@RequestBody与@RequestParam
区别:
- @RequestParam用于接收url地址传参,表单传参[application/x-www-form-urlencoded]
- @RequestBody用于接收json数据[application/json]
应用:
- 后期开发中,发送json格式数据为主,@RequestBody应用较广
- 如果发送非json格式数据,选用@RequestParam接收请求参数
日期类型参数
名称:@DateTimeFormat
类型:类注解
位置:SpringMVC控制器方法形参前面
作用:设定日期时间型数据格式
范例:
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(@DateTimeFormat(pattern="yyyy-MM-dd") Date date){
System.out.println("参数传递 date ==> "+date);
return "{'module':'data param'}";
}
属性:pattern:日期时间格式字符串
日期类型参数:(Date date,
@DateTimeFormat(pattern=”yyyy-MM-dd”) Date date1,
@DateTimeFormat(pattern=”yyyy/MM/dd HH:mm:ss”) Date date2)
类型转换器
Converter接口
public interface Converter<S,T>{
@Nullable
T convert(S var1);
}
- 请求参数年龄数据(String -> Integer)
- 日期格式数据(String -> Date)
@EnableWebMvc功能之一:根据类型匹配对应的类型转换器
响应
响应页面
响应数据
- 文本数据
- json数据
名称:@ResponseBody
类型:方法注解
位置:SpringMVC控制器方法定义上方
作用:设置当前控制器返回值作为响应体
范例:
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("save ...");
return "{'info':'springmvc'}";
}
REST风格
REST简介
REST(Representational State Transfer),表现形式转换–访问网络资源的格式
传统风格资源描述形式:
REST风格描述形式:
优点:
- 隐藏资源的访问行为,无法通过地址得知对资源是何种操作
- 书写简化
按照REST风格访问资源时使用行为动作区分对资源进行了何种操作:
- http://localhost/users 查询全部用户信息 GET(查询)
- http://localhost/users/1 查询指定用户信息 GET(查询)
- http://localhost/users 添加用户信息 POST(新增/保存)
- http://localhost/users 修改用户信息 PUT(修改/更新)
- http://localhost/users/1 删除用户信息 DELETE(删除)
注意事项:上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范
描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:users、books、accounts …
根据REST风格对资源进行访问称为RESTful
RESTful入门案例
步骤:
设定http请求动作(动词)
@RequestMapping(value="/users", method = RequestMethod.POST)
设定请求参数(路径变量)
@RequestMapping(value="/users/{id}", method = RequestMethod.POST) @ResponseBody public String delete(@PathVariable Integer id){ System.out.println("user delete ..." + id); return "{'module':'user delet'}"; }
REST快速开发
名称:@RestController
类型:类注解
位置:基于SpringMVC的RESTful开发控制器类定义上方
作用:设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能
范例:
@RestController
public class BookController{
}
名称:@GetMapping @PostMapping @PutMapping @DeleteMapping
类型:方法注解
位置:基于SpringMVC的RESTful开发控制器方法定义上方
作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,例如@GetMapping对应GET请求
范例:
@GetMapping("/{id}")
public String getById(@PathVariable Integer id){
System.out.println("book getById ..." + id);
return "{'module':'book getById'}";
}
案例:基于RESTful页面数据交互
步骤:
制作SpringMVC控制器,并通过Postman测试
@RestController @RequestMapping("/books") public class BookController{ @PostMapping public String save(@RequestBody Book book){ System.out.println("book save ==> " + book); return "{'module':'book save success'}"; } @GetMapping public List<Book> getAll(){ System.out.println("book getAll is running ..."); List<Book> bookList = new ArrayList<Book>(); Book book1 = new Book(); book1.setType("计算机"); book1.setName("SpringMVC入门教程"); book1.setDescription("小试牛刀"); bookList.add(book1); //模拟数据... return bookList; } }
设置对静态资源放行
@Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport{ @Override protected void addResourceHandlers(ResourceHandlerRegistry registry){ //当访问/pages/???时候,走/pages目录下的内容 registry.addResourceHandler("/pages/**").addResourceLocations("/pages/"); } }
前端页面通过异步提交访问后天控制器
//添加 saveBook(){ axios.post("/books",this.formData).then((res)=>{}); }, //this.formData表示要保存的数据 //主页列表查询 getAll(){ axios.get("/books").then((res)=>{ this.dataList = res.data; }) } //res.data是返回的数据
SSM整合
SSM整合流程
Spring整合MyBatis
记得事务处理
Spring整合Spring MVC
表现层数据封装
概念:前端接收数据格式–封装特殊消息到message(msg)属性中
设置统一数据返回类
public class Result{
private Object data;
private Integer code;
private String msg;
}
注意事项:Result类中的字段并不是固定的,可以根据需要自行增减。提供若干个构造方法,方便操作!
设置统一数据返回结果编码
public class Code{
public static final Integer SAVE_OK = 20011;
public static final Integer DELETE_OK = 20021;
public static final Integer SAVE_ERR = 20010;
public static final Integer DELETE_ERR = 20020;
}
注意事项:Code类的常量设计也不是固定的,可以根据需要自行增减
根据情况设定合理的Controller
异常处理器
程序开发过程中不可避免的会遇到异常现象
各个层级均出现异常,异常处理代码书写在哪一层–所有的异常均抛出到表现层进行处理
表现层处理异常,每个方法中单独书写,代码书写量巨大且意义不强,如何解决–AOP思想
Spring为了不让开发者去做AOP,创造了:异常处理器
异常处理器:集中、统一的处理项目中出现的异常
@RestControllerAdvice
public class ProjectExecptionAdvice{
@ExecptionHandler(Exception.class)
public Result doExecption(Exception ex){
return new Result(666,null);
}
}
项目异常处理方案
项目异常分类:
业务异常
规范的用户行为产生的异常
不规范的用户行为操作产生的异常
系统异常
项目运行过程中可预计且无法避免的异常
其他异常
编程人员未预期到的异常
项目异常处理方案:
业务异常
发送对应消息传递给用户,提醒规范操作
系统异常
发送固定消息传递给用户,安抚用户
发送特定消息给运维人员,提醒维护
记录日志
其他异常
发送固定消息传递给用户,安抚用户
发送特定消息给开发人员,提醒维护(纳入预期范围内)
记录日志
自定义项目系统级异常
public class SystemException extends RuntimeException{
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public SystemException(Integer code, String message) {
super(message);
this.code = code;
}
public SystemException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
自定义项目业务及异常
public class BusinessException extends RuntimeException{
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public BusinessException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
自定义异常编码
设置触发自定义异常
@Service
public class BookServiceImpl implements BookService{
@Autowired
private BookDao bookdao;
public Book getById(Integer id){
if(id < 0){
throw new BusinessException(Code.PROJECT_BUSINESS_ERR,"请勿进行非法操作!");
}
return bookdao.getById(id);
}
}
拦截并处理异常
@RestControllerAdvice
public class ProjectExceptionAdvice {
//@ExceptionHandler用于设置当前处理器类对应的异常类型
@ExceptionHandler(SystemException.class)
public Result doSystemException(SystemException ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
return new Result(ex.getCode(),null,ex.getMessage());
}
@ExceptionHandler(BusinessException.class)
public Result doBusinessException(BusinessException ex){
return new Result(ex.getCode(),null,ex.getMessage());
}
}
案例:SSM整合标准开发
拦截器
拦截器概念
首先回顾一下web应用是如何工作的:
概念:拦截器是一种动态拦截方法调用的机制
作用:
- 在指定的方法调用前后执行预先设定后的代码
- 阻止原始方法的执行
拦截器与过滤器区别:
- 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
- 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强
入门案例
制作拦截器功能类:
声明拦截器的bean,并实现HandlerInterceptor接口(注意:扫描加载bean)
@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {
@Override
//原始方法调用前执行的内容
//返回值类型可以拦截控制的执行,true放行,false终止
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String contentType = request.getHeader("Content-Type");
HandlerMethod hm = (HandlerMethod)handler;
System.out.println("preHandle..."+contentType);
return true;
}
@Override
//原始方法调用后执行的内容
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
@Override
//原始方法调用完成后执行的内容
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...");
}
}
preHandle()方法返回false的话,就不会执行处理器
配置拦截器的执行位置:
定义配置类,继承WebMvcConfigurationSupport,实现addInterceptor方法(注意:扫描加载配置)
添加拦截器并设定拦截的访问路径,路径可以通过可变参数设置多个
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Autowired
private ProjectInterceptor projectInterceptor;
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
}
@Override
protected void addInterceptors(InterceptorRegistry registry) {
//配置拦截器
registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
}
}
也可以使用标准接口WebMvcConfigurer简化开发(注意:侵入式较强):
@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor projectInterceptor;
@Autowired
private ProjectInterceptor2 projectInterceptor2;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置多拦截器
registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
}
}
拦截器工作流程分析
拦截器参数
前置处理:
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception{
System.out.println("preHandle...");
return true;
}
参数:
- request:请求对象
- response:响应对象
- handler:被调用的处理器对象,本质上不是一个方法对象,对反射技术中的Method对象进行了再包装
返回值:返回值为false,被拦截的处理器将不执行
后置处理:
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception{
System.out.println("postHandle...");
}
参数:modelAndView,如果处理器执行完成具有返回结果,可以读取到数据与页面信息,并进行调整
完成后处理:
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception{
System.out.println("afterCompletion...");
}
参数:ex:如果处理器执行过程中出现异常现象,可以针对异常情况进行单独处理
拦截器链
配置代码见–入门案例:使用标准接口WebMvcConfigurer简化开发
多拦截器执行顺序:
SpringBoot
SpringBoot入门
SpringBoot概述
概述:SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程度上缩短了项目周期。
Spring缺点:
- 配置繁琐
- 依赖繁琐
SpringBoot功能:
- 自动配置
- 起步依赖
- 辅助功能
SpringBoot并不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式
SpringBoot快速入门
需求:搭建SpringBoot,定义HelloController.hello()方法,返回“Hello SpringBoot!”
实现步骤:
- 创建Maven项目
- 导入SpringBoot起步依赖
- 定义Controller
- 编写引导类
- 启动测试
SpringBoot起步依赖原理分析
SpringBoot配置
配置文件分类
SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(yaml)进行配置:
properties:
server.port=8080
yml:
server:
port: 8080
优先级:application.properties > application.yml > application.yaml
获取数据
读取配置内容:
- @Value
- Enviroment
- @ConfigurationProperties
Profile
我们在开发SpringBoot应用时,通常同一套程序会被安装到不同环境,比如:开发、测试、生产等。其中数据库地址、服务器端口等等配置都不同,如果每次打包时,都要修改配置文件,那么非常麻烦。Profile功能就是来进行动态配置切换的。
Profile配置方式:
- 多profile文件方式
- yml多文档方式
Profile激活方式:
配置文件
虚拟机参数
命令行参数
java -jar xxx.jar –spring.profiles.active=pro
配置加载顺序
内部配置加载顺序:
SpringBoot程序启动时,会从以下位置加载配置文件:
- file:./confog/ :当前项目下的/config目录下
- file:./ :当前项目的根目录
- classpath:/config/:classpath的/config目录
- classpath:/ :classpath的根目录
加载顺序为上文的排列顺序,高优先级配置的属性会生效
外部配置加载顺序:
通过官网查看外部属性加载顺序:
SpringBoot整合其他框架
SpringBoot整合Junit
实现步骤:
创建SpringBoot工程
引入starter-test起步依赖
编写测试类
添加测试相关注解
@RunWith(SpringRunner.class)
@SpringBootTest(classes = 启动类.class)
编写测试方法
SpringBoot整合Redis
实现步骤:
- 创建SpringBoot工程
- 引入redis起步依赖
- 配置redis相关属性
- 注入RedisTemplate模板
- 编写测试方法,进行测试
SpringBoot整合MyBatis
实现步骤:
- 创建SpringBoot工程
- 引入MyBatis起步依赖,添加MySQL驱动
- 编写DataSource和MyBatis相关配置
- 定义表和实体类
- 编写dao和mapper文件/纯注解开发
- 测试
SpringBoot高级
SpringBoot自动配置
Condition
Codition是在Spring4.0增加的条件判断功能,通过这个功能可以实现选择性的创建Bean操作
思考:SpringBoot是如何知道要创建哪个Bean的?比如SpringBoot是如何知道要创建RedisTemplate的?
需求:在Spring的IOC容器中有一个User的Bean,现要求:
- 导入Jedis坐标后,加载该Bean,没导入,则不加载
- 将类的判断定义为动态的。判断哪个字节码文件存在可以动态指定
@Enable*注解
SpringBoot中提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的。而其底层原理是使用@Import注解导入一些配置类,实现Bean的动态加载
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@Import提供4种用法:
- 导入Bean
- 导入配置类
- 导入ImportSelector实现类,一般用于加载配置文件中的类
- 导入ImportBeanDefinitionRegistrar实现类
@EnableAutoConfiguration注解
@EnableAutoConfiguration注解内部使用@Import(AutoConfigurationImportSelector.class)来加载配置类
配置文件位置:META-INF/spring.factories,该配置文件种定义了大量的配置类,当SpringBoot应用启动时,会自动加载这些配置类,初始化Bean
并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean
自定义配置案例
需求:自定义redis-starter。要求当导入redis坐标时,SpringBoot自动创建Jedis的Bean
实现步骤:
- 创建redis-spring-boot-autoconfigure模块
- 创建redis-spring-boot-starter模块,依赖redis-spring-boot-autoconfigure的模块
- 在redis-spring-boot-autoconfigure模块中初始化Jedis的Bean。并定义META-INF/spring.factories文件
- 在测试模块中引入自定义的redis-starter依赖,测试获取Jedis的Bean,操作redis
SpringBoot监听机制
SpringBoot的监听机制,其实是对Java提供的事件监听机制的封装
Java中的事件监听机制定义了以下几个角色:
- 事件:Event,继承java.util.EventObject类的对象
- 事件源:Source,任意对象Object
- 监听器:Listener,实现java.util.EventListener接口的对象
SpringBoot在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成一些操作:
ApplicationContextInitializer、SpringApplicationRunListener、CommandLineRunner、ApplicationRunner
SpringBoot启动流程分析
SpringBoot监控
SpringBoot自带监控功能Actuator,可以帮助实现对程序内部运行情况监控,比如监控情况、Bean加载情况、配置属性、日志信息等
使用步骤:
导入依赖坐标:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
图形化监控–Spring Boot Admin
Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序
Spring Boot Admin有两个角色,客户端(Client)和服务端(Server)
应用程序作为Spring Boot Admin Client向Spring Boot Admin Server注册
Spring Boot Admin Server的UI界面将Spring Boot Admin Client的Actuator Endpoint的一些监控信息展示
使用步骤:
- 标题: Java SSM框架
- 作者: 宣胤
- 创建于: 2023-06-06 21:51:38
- 更新于: 2023-06-21 00:04:27
- 链接: http://xuanyin02.github.io/2023/06069152.html
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。