1)官网:https://spring.io/
2)简介:(简化 Spring 开发的框架)(对 Spring 整个技术栈的大整合)
(约定大于配置)(入门容易,精通难)
3)优点:
-1:能够快速创建,可独立运行的 Spring 项目,以及对主流框架的集成。
-2:使用 嵌入式的 Servlet 容器,应用无需打成 WAR 包。
-3:starters 自动依赖 与 版本控制,简化构建配置。
-4:大量的 自动配置Spring 生态圈, 以及第三方功能的整合,简化开发,也可修改默认值。
-5:无需配置编写 XML;无代码生成,开箱即用。
-6:提供 准生产级别的 运行时应用监控、健康检查及外部化配置。
-7:与 微服务、云计算的,天然集成。
4)环境准备:
-1:JDK、Maven、Idea、Spring
1)需求:浏览器发送请求,服务器接收请求,并响应 “Hello World”。
2)创建 maven 项目:(jar)
3)引入 SpringBoot 相关依赖 & starters:
-- 父依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
</parent>
-- 父依赖的父依赖:管理所有依赖的版本
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
4)创建主程序 & 编写接口:
@SpringBootApplication
public class SpringBootHelloWorld {
public static void main(String[] args) {
SpringApplication.run(SpringBootHelloWorld.class, args);
}
}
@RestController
public class TestControlelr {
@RequestMapping(value = "/helloworld")
public String helloworld() {
return "helloworld";
}
}
5)简化部署,可直接 java -jar 启动:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
6)mvn 打包后、启动运行:(java -jar)
1)依赖管理:
-1:在 父依赖的 父依赖里,进行全部启动器的,版本控制。
2)场景启动器:
-1:SpringBoot 将所有的功能场景,都抽取出来:做成一个个的 Starters(场景启动器)。要用什么功能,就导入什么场景启动器。
-2:只要引入 stater:这个场景所有常规的依赖,都会自动引入。
<!-- springboot 场景启动器 -->
帮我们倒入了,web 模块正常运行,所依赖的组建。
<!-- spring-boot-starter-* -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 第三方 场景启动器。 -->
<!-- *-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
3)自动配置原理:(P7)(P19)
-1:
-2:
-3:
-4:
-5:
1)简介:
-1:properties 优先级 大于 yml:如果先加载了 properties,就不管 yml 里面的值。
-2:
-3:
-4:
-5:
2)使用:(ConfigurationProperties)
-1:vo 类 User:
@NoArgsConstructor
@AllArgsConstructor
@Data
@ConfigurationProperties(prefix = "user.aa")
@Component
public class User {
private String name1;
private String name2;
private String name3;
private Integer age;
private boolean aBoolean;
private Date myDate;
private LocalDateTime myLocalDateTime;
private List myList1;
private List myList2;
private Set mySet1;
private Set mySet2;
private Map myMap1;
private Map myMap2;
private List<Map<String, Pet>> petList;
private Map<String, List<Pet>> petMap;
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@Component
class Pet {
private String petName;
private Integer petAge;
}
-2:yaml 配置值
user:
aa:
name1: 张三 \n 李四
name2: '张三 \n 李四'
name3: "不会转译特殊字符 \n 李四"
age: 14
my-date: 2020/12/12
# my-local-date-time:
my-map1:
k1: v1
k2: v2
my-map2: { k1: v1,k2: v2 }
my-list1: [ list1,list2,list3 ]
my-list2:
- list1
- list2
- list3
my-set2: [ set1,set2,set3 ]
my-set1:
- set1
- set2
- set3
# pet-map:
# pet-list:
-3:查看配置结果:
@RestController
public class TestController {
@Autowired
private User user;
@RequestMapping(value = "/hello")
public User hello() {
return user;
}
}
3)官方建议,导入配置文件处理器:XML:(编写 yaml 时,就会有提示了)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<!-- 打包时候排除 ,要不打包之后类太多了,打包时间变长 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
1)vo.User 类:
@Component
public class User {
@Value("${user.aa.name1}")
private String name1;
}
2)Yaml 文件配置:
user:
aa:
name1: 张三 \n 李四
3)相同 & 不同:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1)配置文件中,可使用的随机数:
(第一次生成后,不会改变)
a: ${random.value}
a: ${random.int}
a: ${random.long}
a: ${random.int(10)}
a: ${random.int(10,200)}
2)属性配置占位符:
server:
port: 8080
port:
value1: ${server.port}
value2: ${server.port}123
# 实际输出结果:8080123
1)说明:
-1:Profile 是 Spring 对不同环境,提供不同配置功能的支持。
-2:可以通过激活、指定参数等方式,快速切换应用环境。
2)多 profile 文件形式的格式:
application.yml -- 默认配置文件,任何时候都会加载
application-dev.yml -- 指定环境配置文件
application-prod.yml
3)激活 指定 环境:
-1:application.yml:配置文件中,指定环境。(优先级最低,会被后面命令行覆盖)
spring:
profiles:
active: dev
-2:命令行,启动时激活:
(会覆盖配置文件配置,会被虚拟机参数覆盖)
--spring.profiles.active=prod
java -jar springboot.jar --spring.profiles.active=prod
-3:虚拟机参数:VM options 激活:(优先级最高)(优先级 > 命令行配置)
-Dspring.profiles.active=prod
4)环境分隔符:(用得少,不同环境基本都是不同的文件)
spring:
profiles:
active: dev
---
spring:
profiles: dev
server:
port: 8081
---
spring:
profiles: prod
server:
port: 8082
5)使用注解配置,在不同环境下生效:
@Profile(value = "dev")
@Bean
public MyFilter myFilter() {
return new MyFilter();
}
2)注意 & 说明:
-1:以上是按照,优先级:从高到低的顺序。
-2:所有位置的文件,都会被加载;高优先级的配置内容,会覆盖低优先级配置内容。
-3:高优先级 与 低优先级,都会被加载,并形成互补配置。
-4:也可以通过配置:spring.config.location 来改变默认配置。(java -jar 启动时,进行指定)
1、-- 启动时,加载指定配置文件,配置文件可省略 .properties。(也可使用注解加载)
java -jar xxx.jar --spring.config.name=myapp
2、-- 启动时,指明配置文件所在目录.(注意,要以 / 结束)
java -jar xxx.jar --spring.config.location=classpath:/
3、--直接指定指定路径的,指定配置文件。(配置文件中 或者 命令行启动时)
spring.config.location=D://aaa.properties
1)官网文档配置文件顺序说明:https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#
2)常用的:
(高优先级 --> 低优先级)
(高优先级会覆盖低优先级的配置)
(所有配置文件,会形成互补配置)
3)总结:
-1:命令行参数:
官网说明:https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging
1)日志框架所需要的功能:
-1:异步记录;
-2:自动归档;
-3:日志的一个抽象层,做出不同日志实现框架;
2)市面上的日志框架:
-1:JUL、JCL、Jboss-logging、Logback、Log4j、Log4j2、Slf4j。
3)众多日志框架的关系:( Log4j & Logback 是同一个人写的)(Logback 是升级版)
4)最终选择:
-1:Spring 框架:默认使用 JCL;
-2:Spring Boot 框架:( SLF4j + Logback )
1)如何在系统中使用 SLF4j:
-1:以后在开发过程中,对日志记录方法对调用:不应该直接调用日志的实现类,而是调用日志抽象层里面的方法。
-2:依赖使用:给系统中导入:( SLF4j + Logback实现 ) 的依赖。
2)官网说明:
-1:SLF4j 官网使用手册:https://www.slf4j.org/manual.html
-2:官网的使用方法:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
private static Logger logger = LoggerFactory.getLogger(HelloWorld.class);
public static void main(String[] args) {
logger.info("Hello World");
}
}
-3:官网的日志依赖关系图:(Logback & slf4j)
3)日志配置文件说明:
-1:每一个日志的实现框架,都有自己的配置文件。
-2:使用 SLF4j 以后:配置文件还是做成,不同日志实现框架的,自己本身的配置文件。
1)遗留问题:
-1:系统 A( slf4j + logback )
-2:但是其中,不同框架日志并不相同:Spring( commons-logging) 、 Hibernate( jboss-logging ) 、 Mybatis 、 xxx。
2)官网解决方案:https://www.slf4j.org/legacy.html
3)如何让 系统中所有的日志,都统一到 slf4j:
-1:将系统中,其他日志框架,先排除。
-2:用中间包,来替换原有的日志框架。
-3:导入想要使用的, slf4j 其他的实现。(比如:Logback)
1)Spring Boot 日志依赖关系图:
2)Spring Boot 日志依赖关系梳理:
-1:spring boot 依赖的 starters
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
-2:SpringBoot 使用它来做日志功能:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
-3:点进去:
-- 使用 logback 做日志记录
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
-- 把其他日志,转化为 slf4j
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</dependency>
4)总结:
-1:Spring Boot 底层,也是使用 slf4j + logback 的方式,进行日志记录。
-2:Spring Boot 也把其他的日志,替换为了 slf4j 。
-3:中间的替换包:见上图。
-4:注意:如果我们,要引入其他框架?一定要把这个框架的默认日志依赖,移除掉。(否则会 jar 包冲突)
-5:Spring Boot 能够自动适配所有的日志,而且底层使用 ( slf4j + Logback )的方式,记录日志。引入其他框架的时候,只需要把其他框架默认的日志依赖的排除掉。
1)SpringBoot 已经默认配置好了日志,直接使用就可以。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
private static Logger logger = LoggerFactory.getLogger(HelloWorld.class);
public static void main(String[] args) {
-- 日志的级别从低到高,
logger.trace("trace");
logger.debug("debug");
logger.info("info"); -- springBoot 默认级别
logger.warn("warn");
logger.error("error"); -- 线上配置的级别
}
}
2)配置日志打印级别:
(配置 info 级别,日志就会在 info级别 及 以后的高级级别生效)
logging:
level:
root: info
logging:
level:
com.example: error
-- 打印结果
2022-05-16 17:54:32.067 INFO 2950 --- [ main] c.e.s.Springboot2AnnotationApplication : info
2022-05-16 17:54:32.067 WARN 2950 --- [ main] c.e.s.Springboot2AnnotationApplication : warn
2022-05-16 17:54:32.067 ERROR 2950 --- [ main] c.e.s.Springboot2AnnotationApplication : error
3)指定日志配置文件位置:
-1:配置文件中指定:日志文件输出位置:
-2:( name / path )二选一:【 name 与 path 是冲突的。(有了 name,path 就失效)】
logging:
level:
com.example: trace
file:
-- (默认配置在,项目的当前跟路径下。)
name: my.log
-- (只指定配置文件路径即可,spring.log 为默认的日志文件名称。)
path: /Users/zhangsan/workspacestudy/a5_5_springcloud/springboot_2_annotation/logfile/logfile
-- 设置在控制台输出的格式
-- 格式如下
pattern:
file: %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n
-3:配置文件 案例:( logback.xml )
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<contextName>logback</contextName>
<property name="log.path" value="F:\\logback.log" />
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- <filter class="com.example.logback.filter.MyFilter" /> -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<appender name="file"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
<logger name="com.example.logback" level="warn" />
</configuration>
4)指定日志文件:
-1:logback 默认的配置文件在:base.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Base logback configuration provided for compatibility with Spring Boot 1.1
-->
<included>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
-- 指定 控制台输出的
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
-- 指定文件输出的
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
-- 指明了默认为:info 级别
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</included>
-2:定义自己的 logback 配置文件:
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging.custom-log-configuration
5)日志 profile 功能:
-1:profile 功能:需要使用 logback-spring.xml 配置文件;
(可以但没必要)
1)切换方法:照着 slf4j官网 日志关系图,替换依赖:
-1:去除多余依赖。
-2:导入新的依赖。
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1)说明:
-1:SpringBoot 默认使用 Tomcat,作为嵌入式的 Servlet 容器:
2)提出问题:
-1:如何定制修改 Servlet 容器相关配置。
1:修改 和 Servlet 有关的配置( ServerProperties )
server:
port: 8080
servlet:
context-path: /api
# 通用的 servlet 配置
tomcat:
connection-timeout: 3
uri-encoding: UTF-8
2:编写一个【 EnbeddedServletContainerCustomizer 】:嵌入式的 Servlet 容器的定制器;来修改 Servlet 容器的配置。
-2:SpringBoot 能不能支持,其他的 Servlet 容器。
3)如何注册 Servlet 三大组件:(Servlet、Filter、Listener)
(由于: SpringBoot 默认是以 jar 包的方式,启动嵌入式 Servlet 容器,来启动 SpringBoot 的 web 应用,所以没有 web.xml 配置文件)
-1:Servlet:
(dispatcher 就是这样注册的:DispatcherServletAutoConfiguration)
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.write("123456");
writer.flush();
writer.close();
}
}
// 注册 servlet 方式 1:
@Configuration
public class MyServerConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean() {
// /*:会拦截 jsp,/:不会
ServletRegistrationBean registrationBean =
new ServletRegistrationBean(new MyServlet(), "/myservlet");
return registrationBean;
}
}
// 注册 servlet 方式 2:
@WebServlet(urlPatterns = "/myservlet")
public class MyServlet extends HttpServlet {xxxx}
----------------------------------------------------------------
//指定 原生 Servlet 组件都放在哪
@ServletComponentScan(basePackages = "com")
@SpringBootApplication
public class Springboot2AnnotationApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(Springboot2AnnotationApplication.class, args);
}
}
-2:Filter:
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
System.out.println("MyFilter 》》》init()");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("MyFilter 》》》doFilter()");
// 继续执行请求
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("MyFilter 》》》destroy()");
}
}
// 注册 filter 方式 1:
@Configuration
public class MyFilterConfig {
@Bean
public FilterRegistrationBean myFilterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new MyFilter());
filterRegistrationBean.addUrlPatterns(new String[]{"/*", "/myservlet"});
return filterRegistrationBean;
}
}
// 注册 filter 方式 2:
@WebFilter(urlPatterns = {"/css/**", "/js/**"})
public class MyFilter implements Filter {XXX}
-3:Listener:(1):监听 Servlet 事件(两种配置方式)
/**
* 注册监听器方式 (1):【 @Component 注解方式 】
*/
@Component // 二选一:第二种方式的话需删除此行
@WebListener // 二选一:第二种方式的话需删除此行。(一般用这个)
public class My2Listener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("servlet 初始化");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("servlet 销毁");
}
}
/**
* 注册监听器方式 (2):【 MyListener 去掉 @Component 】
*/
@Configuration
public class MyListenerConfig {
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean() {
ServletListenerRegistrationBean<My2Listener> registrationBean = new ServletListenerRegistrationBean();
registrationBean.setListener(new My2Listener());
return registrationBean;
}
}
-3:Listener:(2):监听 自定义事件
// 自定义事件类型
public class MyApplicationEvent extends ApplicationEvent {
public MyApplicationEvent(Object source) {
super(source);
}
}
// 监听事件:
// (上面还有另一种注册方法:ServletListenerRegistrationBean)
@Component
public class MyListener implements ApplicationListener<MyApplicationEvent> {
@Override
public void onApplicationEvent(MyApplicationEvent event) {
System.out.println("监听到事件::" + event.toString());
System.out.println("event.getSource()::" + event.getSource());
System.out.println("event.getTimestamp()::" + event.getTimestamp());
}
}
// 发布事件:
public static void main(String[] args) throws InterruptedException {
ConfigurableApplicationContext context = SpringApplication.run(Springboot2AnnotationApplication.class, args);
context.publishEvent(new MyApplicationEvent("??我发布了一个事件??"));
}
1)Jetty:
-1:优点:更适合做长连接的场景。(例如:web 聊天)
2)Undertow:
-1:优点:高性能非阻塞的 Servlet 容器,并发性能非常好。
-2:缺点:不支持 JSP。
3)转换方法:
-1:去除 web 中的 tomcat:
<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>
-2:切换 undertow:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
(P49-P50)
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
(P51-P52)
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
(Data、jpa、mybatis)
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
(redis)
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
(elasticsearch)
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
(邮件任务、定时任务、异步任务)
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
(spring secutiry)
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
(zk + dubbo)(boot + cloud)
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
(运维)
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
1):
-1:
-2:
-3:
-4:
-5:
2):
-1:
-2:
-3:
-4:
-5:
3):
-1:
-2:
-3:
-4:
-5:
4):
-1:
-2:
-3:
-4:
-5:
5):
-1:
-2:
-3:
-4:
-5:
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- nryq.cn 版权所有 赣ICP备2024042798号-6
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务