download:www.666xit.com/4282/
SpringBoot3+Vue3 开发高并发秒杀抢购系统
// 声明Student Record public record Student(Integer id, String name){ } // 创立Record目标 Student student = new Student(001, "John");
Record和Class相比,有以下特色:
首要Record是public拜访器,带有全部参数的结构办法,且自带toString(),hashCode(),equals()办法;
其次是隐式的final类,不能被承继,特点也是final,经过结构办法创立后不可修改;
终究,没有set(),get()办法,不能声明实例特点,能声明static特点。
public record Student(Integer id, String name){ // 紧凑结构办法 public Student {} // 自界说结构办法 public Student(String name) { this(null, name); } }
除了全部参数的结构办法,还供给紧凑结构办法和自界说结构办法。
Switch
int week = 2; String memo = ""; switch (week) { case 1,7 -> memo = "weekend"; case 2,3,4,5,6 -> memo = "workday"; default -> throw new IllegaArgumentExcepting("Ineffective date"); }
支撑运用箭头->,->和:不能混用。
int week = 2; String memo = switch (week) { case 1,7 : yield "weekend"; case 2,3,4,5,6 : yield = "workday"; default -> throw new IllegaArgumentExcepting("Ineffective date"); }
运用yield关键字回来成果。
Text Block
// 榜首行必须是三个双引号
String colors = """
red
green
blue
"""; colors.indent(4);
文本块在运用时和一般字符串没有差异,但文本块中的缩进会被主动去除,要保存左边的缩进,需求运用Tab键按需移动或许运用indent()办法。
另外还能够运用formatted()办法进行格式化;运用stripIndent()办法删去每行最初和结束的空格;运用translateEscapes()转义字面量。
Var
var num = 0; var name = "John"; var customer = getCuntomer();
var是一个保存字不是关键字,用于声明局部变量。必须有初值。
能够替代显现类型,让代码简洁,但也降低了程序的可读性。
sealed
// 声明sealed类 public sealed class Shape permits Circle, Square, Rectangle { } // 声明子类 // final 子类不能被承继,依然是密封的 public final class Circle extends Shape { } // sealed 子类也是密封类,仍需求指定子类完结 public sealed class Square extends Shape permits RoundSquare { } // non-sealed 子类非密封类,能够被恣意类承继 public non-sealed class Rectangle extends Shape { } public class Line extends Rectangle { }
sealed类首要特色是约束承继,回绝无限的扩张。
Spring Boot的特性
1创立独立的Spring运用程序,而且内嵌Web容器;
2供给主动化装备starter功用,简化Maven装备;
3没有代码生成,无需XML装备就能尽可能地主动装备好Spring和第三方结构;
4开箱即用,运用脚手架创立项目后,一切根底装备就已经完结;
5约定优于装备,界说了常用类,包的方位和结构,代码不需做任何调整,项目就能依照预期运转。
与Spring,Spring Cloud的联系
Spring Boot和Spring都能够创立Spring运用程序,不同的是Spring Boot消除了设置Spring运用程序所需的XML装备,更快更高效更易用。
Spring Cloud是一些列结构的有序组合,供给了快速构建分布式体系中常用东西。而Spring Boot是每个独立的微服务的平台。
Spring Boot3中的变化
1.JDK支撑版别17-20
2.更新Servlet6.0标准
3.支撑Jackson2.14
4.SpringMVC默许运用PathpatternParser,删去过时的FreeMarker和JSP支撑
5.对第三方库更新版别支撑
6.底层依靠从Java EE迁移到Jakarta EE API。
7.支撑GraalVM原生镜像,将Java运用编译为本机代码,供给显著的内存和气动性能改进。
8.支撑Ahead Of Time(运转前编译)。
9.SpringHttp客户端供给根据Micrometer的可调查性跟踪服务,记录服务运转状态
10.其他
运用Spring Boot
从spring-boot-starter-parent开端
starter是一组依靠描述,在运用中参加starter依靠就能够获取Spring相关技能的一站式的依靠和版别。经过starter能够快速发动并运转项目。
starter包含:
依靠坐标和版别;
传递依靠的坐标和版别;
装备类和装备项
// pom.xml
// 在parent标签中指定,表明承继父项目
org.springframework.bootgroupId> spring-boot-starter-parentartifactId> 3.0.1version> parent> // 在依靠管理中单独参加依靠 org.springframework.bootgroupId> spring-boot-starter-parentartifactId> 3.0.1version> dependency> dependencies>
能够运用两种方法参加Spring Boot供给的父项目,从spring-boot-starter-parent承继取得合理的默许值和完好的依靠树,从而快速树立一个Spring Boot项目。
父项目供给以下功用:
1.JDK的基准版别;
2.源码运用UTF-8格式编码;
3.公共依靠版别;
4.主动化的资源过滤,默许把src/main/resources目录下的文件进行打包;
5.maven的占位符是@
6.对maven插件完结默许设置
7.其他
application装备文件
Spring Boot一同支撑properties和yml格式的装备文件,引荐运用yml。默许名称是application。
YAML根本语法规矩:
大小写敏感;
运用空格缩进表明层级联系;
#表明注释,只能单行注释。
// application.yml spring: redis: host:localhost
port:6379 // ReadConfigService.java @Service public class ReadConfigService { // 经过@Value注解获取 @Value("${spring.redis.port:8080}") private String port; @Autowired private Environment environment; // 经过Environment目标获取 public void printConfig() { this.port = environment.getProperty("server.port"); } }
经过@Value注解或许外部化装备的笼统目标Environment能够读取装备文件。
// db.yml spring: datasource: url: jdbc:mysql://... username: operation
password: 123456 // redis.yml spring: redis: host:localhost
sort:6379 // application-test.yml spring: config: activate: on-profile: test // application-dev.yml spring: config: activate: on-profile: dev // application.yml spring: config: import: conf/db.yml, conf/redis.yml
profiles:
active:dev
能够在application.yml中运用import导入多个装备;
运用on-profile和active激活某个环境装备。
绑定Bean
运用@Value每个成员变量只能绑定一个特点。当特点较多时需求需求重复写很多注解。此刻能够运用绑定Bean。将多个装备项绑定到一个Bean,这个强类型的Bean就能拜访到一切的装备数据了。
// application.yml app: host: Lession07-yml
port: 8002 security: username: root
password: 12345 // 第三方库特点 administrator: username: common
password: 123 // ReadConfigBean.java // com.example.config @Configuration(proxyBeanMethods=false) @ConfigurationProperties(prefix="app") public class ReadConfigBean { private String host; private String port; private Security security; @ConfigurationProperties("administrator") @Bean public Security createAdministrator() { return new Administrator(); } } // group-info.properties group.name=testGroup
group.leader=John
group.member=10 // GroupConfigBean.java // com.example.config @Configuration @ConfigurationProperties(prefix="group") @PropertySource(Value="classpath:/group-info.properties") public class GroupConfigBean { private String name; private String leader; private String member; } // Application.java @ConfigurationPropertiesScan({"com.example.config"}) @SpringBootApplication public class Application { ... }
根本原则是界说标准的Java Bean,要有无参结构办法而且包含特点的拜访器。合作@ConfigurationProperties注解一同运用。注解中的prefix特点能够写前缀。
@ConfigurationProperties注解还需求@EnableConfigurationProperties或@ConfigurationPropertiesScan才能起作用,所以终究在发动类上运用扫描注解@ConfigurationPropertiesScan,声明所在的包就完结了。
除了读取简略的特点和集合供给的特点外,将嵌套目标声明为成员变量后,也能够读取到嵌套的特点。
有时候需求读取第三方库的特点,此刻需求运用@Bean注解,将第三方库中的类注入到绑定Bean中,合作@ConfigurationProperties注解,就能读取了。
还能够读取指定的装备文件。详细做法除了运用@ConfigurationProperties注解外,还需求运用@Configuration和@PropertySource注解,指定文件路径。
主动装备
主动装备的注解是@EnableAutoConfiguration。这个注解也被标示在@SpringBootApplication注解上,所以通常是由@SpringBootApplication注解带入。
@EnableAutoConfiguration注解源码上标示了@Import(AutoConfigruationImportSelector.class),这行代码意味着AutoConfigruationImportSelector这个目标也被导入进了IOC容器。
AutoConfigruationImportSelector的作用是导入主动装备类,从META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports读取到要加载的装备类列表。这个文件在2.7版别之前是spring.factories。
另外结构依据pom.xml中装备的xxxstarter发动器,找到相关的xxxAutoConfiguration,然后经过@import注解找到要加载的装备类列表。
终究结构把以上一切的装备类加载到容器中,依据条件注解判定装备是否生效。
SpringBoot中的Spring MVC
控制器 Controller
@Controller注解被声明为@Component,控制器目标本质就是被Spring容器管理的Bean目标。
创立一般的类,界说public办法,类上注解@Controller或许@RestController,这个类就是一个控制器目标。
@RestController表明@Controller + @ResponseBody。
@ResponseBody表明将回来值序列化输出。假如回来值是字符串,直接将字符串写到客户端;假如是一个目标就转化成json串回来。
类上或许办法上注解@RequestMapping和一个Uri,用于将web恳求映射到控制器类的办法,表明这个Uri由这个类或许办法处理。
参数上常用@RequestParam和@RequestBody这两个注解。
恳求参数要与形参一一对应,@RequestParam用来接纳前台传来的键值对参数,@RequestBody用来接纳前台传来的目标,也就是json数据。这两个注解能够一同运用。
一同还能够运用字符流,@RequestHeader注解等接纳参数。
运用Java Bean Validation对参数进行验证。
在Bean的特点上,参加JSR-303注解,完结验证规矩的界说。经过BindingResult获取验证成果。还能够界说组接口,进行分组操作。
常用的JSR-303注解有@Null, @NotNull, @AssertTrue, @AssertFalse等。
模型 Model
简略来说就是传给浏览器的数据,Model目标,ModelAndView目标或许json字符串都是模型。
视图 View
视图用于展示数据,一切的视图类都完结了org.springframework.web.servlet.View接口。
常用的回来值能够是String目标,自界说Object目标,ResponseEntity目标(包含HttpStatus Code和应答数据的结合体)。
SpringMVC的恳求流程
在SpringMVC结构中,DispatcherServlet是中心目标。作为中央调度器,担任接纳对一切Controller的恳求,调用Controller中的办法处理业务逻辑,终究将回来值经过视图处理响应给浏览器。
运用了门面规划模式,是SpringMVC对外的进口,解耦其他组件,使其他组件间互相没有关联。完结了ApplicationContextAware接口,一切能够拜访容器中的一切目标。
详细流程如下:
DispatcherServlet接纳到客户端发送的恳求后,调用HandlerMapping依据URI找到对应的handler和拦截器,组装成HandlerExecutionChain目标并回来;
接着DispatcherServlet依据回来值调用HanderAdapter进行接口转换,调用详细的handler中的办法并回来ModelAndView目标;
DispatcherServlet调用HandlerExceptionResolver处理反常,假如有反常则回来包含反常的ModelAndView目标;
然后DispatcherServlet调用ViewResolver解析ModelAndView目标,回来View目标;
终究DispatcherServlet将得到的View目标进行渲染,填充Model中的数据到request域,回来给客户端响应成果。
SpringMVC中的主动装备
WebMvcAutoConfiguration是SpringMVC的主动装备类,依据类上的注解,有以下几个代表性的装备类。
1.@DispatcherServletAutoConfiguration主动装备DispatcherServlet:创立DispatcherServlet,并注册到容器中,设置load-on-startup = -1;创立MultipartResolver;它的绑定Bean是WebMvcProperties。
2.@WebMvcConfigurationSupport:创立HandlerMapping, HandlerAdapter, HandlerExceptionResolver接口的多个完结目标;PathMatchConfigurar, ContentNegotiationManager, OptionalValidatorFactoryBean, HttpMessageConverter等实例。
在SpringMVC中,Handler的表现形式有多种,所以处理恳求的方法也不同。经过HandlerMapping完结类包装Handler,再由HandlerAdapter接口的完结类调用handler。
平时用的最多的@RequestMapping方法是经过RequestMappingHandlerMapping, RequestMappingHandlerAdapter, DefaultHandlerExceptionResolver, ExceptionHandlerExceptionResolver这几个组件完结的。
3.ValidationAutoConfiguration:装备JSR-303验证器
4.ServletWebServerFactoryAutoConfiguration:SpringBoot依据classpath上存在的类,判别当前运用运用的是Tomcat/Jetty/Undertow中的哪个服务器没从而决议界说相应的Web服务器。
绑定Bean是ServerProperties。
运用Servlet
经过注解@WebServlet界说Servlet目标
@WebServlet(urlPatterns="/helloServlet", name="HelloServlet") public class HelloServlet extends HttpServlet { ... } @ServletComponentScan(basePackages="com.example.servlet") @SpringBootApplication public calss Application { ... }
经过ServletRegistrationBean注册Servlet目标
@Configuration public class WebAppConfig { @Bean public ServletRegistrationBean addServlet() { ServletRegistrationBean registrationBean = new ServletRegistrationBean(); registrationBean.setServlet(new LoginServlet()); registrationBean.addUrlMappings("/user/login"); registrationBean.setLoadOnStartup(1); return registrationBean; } }
运用Filter
经过@WebFilter界说Filter目标
@WebFilter(urlPatterns = "/*") public class LogFilter implements Filter { ... } @ServletComponentScan(basePackages="com.example.filter") @SpringBootApplication public calss Application { ... }
经过FilterRegistrationBean注册Filter目标
@Bean public FilterRegistrationBean addFilter() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); filterRegistration.setFilter(new Filter()); filterRegistration.addUrlPatterns("/*"); filterRegistration.setOrder(1); return filterRegistration; }
运用结构中的Filter
@Bean public FilterRegistrationBean addOtherFilter() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter(); ... filterRegistration.setFilter(filter); ... return filterRegistration; }
运用Listener
运用@WebListener界说Listener
@WebListener public class MySessionListener implements HttpSessionListener { ... } @ServletComponentScan(basePackages="com.example.listener") @SpringBootApplication public calss Application { ... }
经过ServletListenerRegistrationBean注册Filter目标
@Bean public ServletListenerRegistrationBean addListener() { ServletListenerRegistrationBean registration = new ServletListenerRegistrationBean(); registration.setListener(new Filter()); ... return registration; }
运用WebMvcConfigurar定制SpringMVC
界说一个装备类完结接口,并@Override需求的办法
常用的功用有页面跳转控制器,数据格式化,拦截器等
// 完结类 public class DeviceFormatter implements Formatter { ... } public class AuthInterceptor implements HandlerInterceptor [
...
}
@Configuration
public class MvcSettings implements WebMvcConfigurar { // 页面跳转控制器 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/welcome").setViewName("index"); } // 数据格式化 @Override public void addFormatters(FormatterRegistry registry) { registry.addFormatter(new DeviceFormatter()); } // 拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()); .order(1) .addPathPatterns("/**"); .excludePathPatterns("/article/query"); } }
运用MultipartResolver上传文件
MultipartResolver的内部完结类是StandardServletMultipartResolver,封装了Part接口,完结根据Servlet3.0标准的文件上传。
@Controller public class UploadFileController { // 运用MultipartResolver读取POST恳求数据 @PostMapping("/uploadByMultipartResolver") public String uploadM(@RequestParam("uploadFile") MultipartFile multipartFile) { ... } // 运用Part接口完结文件上传 @PostMapping("/uploadByPartInterface") public String uploadP(HttpServletRequest request) { Part part = request.getParts(); ... } }
运用HandlerExceptionResolver处理大局反常
常用的注解:
@ControllerAdvice, @RestControllerAdvice, @ExceptionHandler
@ControllerAdvice
public class GlobalExceptionHandler {
// 处理大局反常
@ExceptionHandler({Exception.class})
public String handlerException(Exception e, Model model) {
...
}
// 校验JSR-303标准验证参数的成果
@ExceptionHandler({BindException.class})
public Map handleJSR303Exception(BindException e) {
BindingResult result = e.getBindingResult();
...
}
}
SpringBoot3中支撑运用ProblemDetail增强反常处理
在RFC7807标准中,对错误信息做了更标准的界说,使反常信息更完善。ProblemDetail类封装了标准字段和扩展字段,作为回来值输出RFC7807标准的字段。
除了ProblemDetail类,还能够运用ErrorResponse处理反常。包含反常信息和完好的REF7807格式的ProblemDetail正文。ErrorResponseException是ErrorResponse接口的一个完结。经过承继ErrorResponseException类,那么这个反常会交给结构处理。
public class BookNotFoundException extends RuntimeException { ... } public class caculErrorException extends RuntimeException { ... } @RestControllerAdvice public class GlobalExceptionHandler { // 运用ProblemDetail处理反常 @ExceptionHandler({BookNotFoundException.class}) public ProblemDetail handleBookNotFoundException(BookNotFoundException e) { ProblemDetail detail = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, e.getMessage()); // 设置标识错误类型的URI detail.setType() ... // 能够设置自界说字段 detail.setProperty("timestamp", Instant.now()); return detail; } // 直接运用ErrorResponse作为反常处理办法的回来值 @ExceptionHandler({caculErrorException.class}) public ErrorResponse handleCaculErrorException (CaculErrorException e) { ErrorResponse error = new ErrorResponseException(HttpStatus.INTERNAL_SERVER_ERROR, e); return error; } // 经过承继ErrorResponseException类,将反常交给结构处理 public class BookNotFoundException extends ErrorResponseException { ... }
长途拜访
SpringBoot3供给了多种长途拜访技能。其间根据HTTP协议的长途拜访运用最广泛。首要界说一个接口,运用@HttpExchange供给HTTP服务;经过生成HTTP客户端WebClient的署理目标,完结长途拜访。WebClient是根据Reactor的非阻塞异步恳求客户端。
声明式
// POJO public class Schedule { ... } // 声明服务接口 public interface ScheduleService { @GetExchange("/schedules/{id}") Schedule getScheduleById(@PathVariable Integer id); } // 创立署理类 @Coufiguration(proxyBeanMethods = false) public class HttpConfiguration { @Bean public ScheduleService requestService() { WebClient webClient = WebClient.builder().baseUrl("https://jsonplaceholder.typicode.com/").build(); return HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build().createClient(ScheduleService.class); } // 调用 public class CallHttpClient { @Resource private ScheduleService service; public Schedule getSchedule(Integer id) { return service.getScheduleById(id); } }
运用接口组合
// POJO public class Schedule { ... } // 声明服务接口 @HttpExchange(url = "https://jsonplaceholder.typicode.com/") public interface ScheduleService { @GetExchange("/schedules/{id}") Schedule getScheduleById(@PathVariable Integer id); } // 创立署理类 @Coufiguration(proxyBeanMethods = false) public class HttpConfiguration { @Bean public ScheduleService requestService() { WebClient webClient = WebClient.create(); return HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build().createClient(ScheduleService.class); } // 自界说装备 @Bean public ScheduleService selfDefiningService() { HttpClient client = HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 30000); WebClient webClient = WebClient.builder() .clientConnector(new ReactorClientHttpConnector(client )); return HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build().createClient(ScheduleService.class); } // 调用 public class CallHttpClient { @Resource private ScheduleService service; public Schedule getSchedule(Integer id) { return service.getScheduleById(id); } }
AOT和GraalVM
JVM提高履行速度的技能有JIT实时编译技能,和在Java9中作为试验性功用的AOT预编译技能。
JIT会发现一些运转频频的热门代码,并将热门代码编译成本地代码。这个进程是在程序履行中进行的,所以完结优化需求时刻。
AOT是静态的,经过Native Image Builder这个东西,预先将代码编译为独立可履行文件Native Image本机镜像。这个编译进程会在项目构建期间完结。
目前,SpringBoot3支撑运用GraalVm中的AOT技能编译,并履行镜像文件。
领取专属 10元无门槛券
私享最新 技术干货