单体应用VS微服务
- 单体应用将应用程序的所有功能打包成1个独立的jar包或war包,运行在同1个进程中
优点:易于测试;易于部署
缺点:开发效率低,所有人在1个项目中开发;
随着业务复杂性的增加,代码越来越复杂
- 微服务
应用技术
- 单体
Spring Boot、Spring MVC、MyBatis、本地缓存Guava Cache、Redis、Spring Mail、Spring Boot Test
- 微服务
SpringBoot优点 3-2
- 内嵌Web容器,默认Tomcat,只要classpath下有spring-boot-starter-web这个jar包,就引入了内嵌Tomcat容器
SpringBoot整合Mybatis
- 引入Mybatis starter
- application.properties/yml 添加spring mybatis和dataSource配置
- 创建Mybatis配置文件,mapper接口类和sql映射文件
[把配置写下面]
基于Spring Boot Admin和Actuator搭建简单监控平台
Actuator能够对应用程序进行监控。它通过REST API来统计和收集应用程序的运行情况,并以JSON形式返回。Actuator内置了很多endpoint,例如
/beans显示Spring容器中的所有Bean,包括Bean的类型,Bean的scope(单例/多例);
/env,应用程序环境变量,包括JDK版本,JVM信息,OS信息,还包括在resources文件夹下的所有的配置;
/health显示健康程度,显示Spring容器、数据库的状态;
/metrics,指标信息,包括内存信息,JVM堆信息,方法区信息,线程个数,线程状态,GC次数;
/mappings显示@Controller中所有@RequestMapping映射;
/autoconfig,SpringBoot自动配置类的信息,包括这些自动配置类在哪种条件(Condition)下会被自动配置;
/shutdown使应用程序优雅的关闭
如果Actuator的这些endpoint开放给用户,系统的信息就暴露出去了,/shutdown默认不开启,如果开启,用户通过/shutdown能够优雅的关闭应用,这肯定是不允许的。
防火墙可以拦截一些端口,决定哪些端口可以被外部访问,哪些端口只能内部访问。使用management.port专门为Actuator配置1个端口,在防火墙中配置这个端口只能被内部访问,外部用户不能访问
Actuator只能返回JSON数据,Spring Boot Admin可以为Actuator提供可视化UI
在这部分中,Actuator是被监控的客户端,Admin是负责监控的服务器端。Actuator需要向Admin注册自己
- 服务器端Admin, 需要在main类中使用@EnableAdminServer标注自己是监控端
- 客户端Actuator,在spring.boot.admin.url配置Admin url,指示Actuator向Admin注册
Spring MVC流程
- 客户端发送HTTP请求,到达Servlet容器,Servlet容器将HTTP请求解析为对象,对象中包括HTTP请求的url、header、body
- 进入用户自定义的Filter,Filter可以对HTTP请求进行处理
- 进入DispatcherServlet,DispatcherServlet是Spring MVC的入口
- DispatcherServlet对url进行解析得到uri,调用处理器映射器HandlerMapping,根据uri寻找处理器Handler,Handler即Controller。HandlerMapping会将Handler和拦截器HandlerInterceptor封装成1个调用链对象HandlerExecutionChain
- 先执行HandlerInterceptor,再执行Handler对象。DispatcherServlet会选择1个合适的处理器适配器HandlerAdapter来执行Handler,在执行Handler前,根据配置,SpringMVC可以为我们做一些额外的工作
(1)使用HTTP消息转换器HttpMessageConverter将请求消息转换为对象,HTTP消息转换器还用来对象转换为响应消息
@RequestBody,将HTTP请求体body中的数据转换为@Controller方法入参
@ResponseBody,将@Controller方法的返回值转换为HTTP响应体body中的数据
(2)数据转换
(3)数据格式化
(4)数据验证 - Handler执行完毕后,向DispathcerServlet返回1个ModelAndView对象,DispatcherServlet根据视图名和视图解析器将视图渲染返回给前台。不过现在一般采用前后端分离的架构,当执行完Handler后,直接将HTTP响应返回给前台
Spring MVC注解
- @Controller 将类标注为处理请求的控制器
- @RequestMapping 映射请求uri和Controller中的方法
- @PathVariable 将url中的占位符绑定到Controller方法入参
@RequestMapping("/register/{userId}/{userId1}")
public String register(@PathVariable("userId") String userId, @PathVariable("userId1") String userId1) {} - @RequestParam 将HTTP请求体中参数绑定到Controller方法入参
JAVA默认不记录方法入参名称,需要使用@RequestParam指定入参对应请求参数名
3个属性 value,对应参数名;required,是否必须,默认true,没有异常;DefaultValue,默认参数值,自动将required设置为false
@RequestMapping(“”)
Public String handler(@RequestParam(value = “userName”, required = false) String userName ){
} - @CookieValue,绑定请求中Cookie
内省机制
对于一般的Java Bean,使用公有的getter和setter方法访问Bean的私有属性,这是默认的规则
内省机制是对JAVA Bean类属性的缺省处理方式,可以在不知道getter和setter方法规则的情况下,对getter和setter方法进行调用。JAVA提供API来访问属性的getter和setter方法,通过这些API,对getter和setter方法进行调用
PropertyDescriptor类是Java Bean的属性描述类,可以用来访问属性的getter和setter方法,主要方法:
- getPropertyType(),获得属性的Class对象;
- Method getReadMethod(),获得用于读取属性值的方法;
- Method getWriteMethod(),获得用于写入属性值的方法;
- hashCode(),获取对象的哈希值;
- Method setReadMethod(Method readMethod),设置用于读取属性值的方法;
- Method setWriteMethod(Method writeMethod),设置用于写入属性值的方法。
(1) 创建PropertyDescriptor对象,构造函数传入属性名和类对象
(2) 使用PropertyDescriptor.getReadMethod()获得读取属性方法的对象,是1个Method类型的对象
(3) 传入类对象和实参,使用Method对象的invoke()对其进行反射调用
工程中使用内省机制,对Bean设置默认值,这样做主要有2个原因:
(1)用于ORM映射的实体类的属性类型,不使用基本数据类型,使用对应的包装类。这样做,是因为JAVA中的基本数据类型有默认值,例如int类型的age默认值为0,age总有值,无法实现age为null的操作;但Integer类型默认为null,所以,实体类中一律没有使用基本数据类型
(2)因为实体类属性都是类,如果不设置,其值为null。数据库字段如果不允许null,插入会失败,而有些字段对业务无影响,我们不希望对于每个类的属性,都调用1次setter方法设置值。所以编写了1个Utils工具类,使用apache的PropertyUtils工具类和内省机制相关的类得到所有类属性,如果其值不为null,跳过;如果其值为null,为其赋上默认值
实体类中属性的类型,只有String,包装类和日期类
(1)所有的包装类都是Number类的子类,所以如果属性是String,其默认值为长度为0的String,如果属性是Number类型,其默认值为0,如果属性是日期,其默认值为当前日期