Spring Environment配置文件获取值 {#spring-environment配置文件获取值}
|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 | java public class 配置获取 { @Resource private static Environment environment; @Value("#{'${alarm.email.user}'.split(',')}") private List<String> alarmEmails; void method(String[] args) { environment.getProperty("env"); } }
|
application.yml:
|-------|------------------------------------------------------------|
| 1 2 3 | yaml alarm: email: recipients: zhangSan,liSi,wangWu
|
分布式锁 {#分布式锁}
|----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | java @Slf4j @RequiredArgsConstructor public class 分布式锁 { private final LockRegistry lockRegistry; void method() { Lock rLock = lockRegistry.obtain("key"); try { if (rLock.tryLock(2, TimeUnit.SECONDS)) { // 执行业务 } } catch (InterruptedException e) { log.error("流程申请新建时并发异常", e); } finally { rLock.unlock(); } } }
|
JPA {#jpa}
|---------|-----------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 | xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
|
|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 | java // JPA 示例 int deleted = demoRepository.deleteAllById(1L); long countById = demoRepository.countById(1L); Demo demo = demoRepository.findOne(Example.of(Demo.builder().id(4L).build())).orElse(null); List<Demo> all = demoRepository.findAll(); List<Demo> all1 = demoRepository.findAll(Example.of(Demo.builder().build())); int updated = demoRepository.updateNameById("-1Name", -1L); PageRequest pageRequest = PageRequest.of(1, 10, Sort.by("id").ascending()); Page<Demo> demoPage = demoRepository.findAll(pageRequest); Example<Demo> example = Example.of(Demo.builder().build(), ExampleMatcher.matching().withIgnoreCase()); List<Demo> demoList = demoRepository.findAll(example);
|
Springboot3.x整合OpenAPI3(整合Swagger3) {#springboot3x整合openapi3整合swagger3}
访问地址:http://localhost:8080/swagger-ui/index.html
|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 | xml <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.6.0</version> </dependency>
|
|----------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | java import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.Collections; @Configuration public class OpenAPIConfig { @Bean public OpenAPI customOpenAPI() { Contact contact = new Contact() .name("zxalive") // 作者名称 .email("1205362172@qq.com") // 作者邮箱 .url("https://zxalive.com/") // 介绍作者的URL地址 .extensions(Collections.emptyMap()); // 使用Map配置信息(如key为"name","email","url") Info info = new Info() .title("Alice接口文档") // Api接口文档标题(必填) .description("Api接口文档描述") // Api接口文档描述 .version("1.2.1") // Api接口版本 .contact(contact); // 设置联系人信息 OpenAPI openAPI = new OpenAPI() .openapi("3.0.1") // Open API 3.0.1(默认) .info(info); return openAPI; // 配置Swagger3.0描述信息 } }
|
|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 | yaml # springdoc-openapi项目配置 springdoc: swagger-ui: path: /swagger-ui.html tags-sorter: alpha operations-sorter: alpha api-docs: path: /v3/api-docs group-configs: - group: 'default' paths-to-match: '/**' packages-to-scan: com.zx.alice.controller
|
SpringBoot3.3.2使用Problem Details (RFC 9457) {#springboot332使用problem-details-rfc-9457}
参考:https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-ann-rest-exceptions.html
基于springboot3.x版本
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | java package com.zx.alice.exception; import jakarta.validation.ValidationException; import org.springframework.beans.ConversionNotSupportedException; import org.springframework.beans.TypeMismatchException; import org.springframework.http.*; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.lang.Nullable; import org.springframework.validation.method.MethodValidationException; import org.springframework.web.*; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MissingPathVariableException; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.ServletRequestBindingException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; import org.springframework.web.context.request.async.AsyncRequestTimeoutException; import org.springframework.web.method.annotation.HandlerMethodValidationException; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.multipart.support.MissingServletRequestPartException; import org.springframework.web.server.ResponseStatusException; import org.springframework.web.servlet.NoHandlerFoundException; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; import org.springframework.web.servlet.resource.NoResourceFoundException; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Optional; /** * 全局异常处理 RFC-9457 */ @ControllerAdvice public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { @Nullable @Override public ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { pageNotFoundLogger.warn(ex.getMessage()); ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleHttpMediaTypeNotAcceptable(HttpMediaTypeNotAcceptableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleMissingServletRequestPart(MissingServletRequestPartException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleServletRequestBindingException(ServletRequestBindingException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { Object[] args = ex.getDetailMessageArguments(); assert args != null; String defaultDetail = args[0] + "" + args[1]; ProblemDetail body = this.createProblemDetail(ex, status, defaultDetail, (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleHandlerMethodValidationException(HandlerMethodValidationException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleNoResourceFoundException(NoResourceFoundException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleErrorResponseException(ErrorResponseException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } /** * 较低级别的异常,以及在客户端和服务器上对称使用的异常 */ @Nullable @Override public ResponseEntity<Object> handleConversionNotSupported(ConversionNotSupportedException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { Object[] args = {ex.getPropertyName(), ex.getValue()}; String defaultDetail = "Failed to convert '" + args[0] + "' with value: '" + args[1] + "'"; ProblemDetail body = this.createProblemDetail(ex, status, defaultDetail, null, args, request); return handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { Object[] args = {ex.getPropertyName(), ex.getValue()}; String defaultDetail = "Failed to convert '" + args[0] + "' with value: '" + args[1] + "'"; String messageCode = ErrorResponse.getDefaultDetailMessageCode(TypeMismatchException.class, null); ProblemDetail body = this.createProblemDetail(ex, status, defaultDetail, messageCode, args, request); return handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleHttpMessageNotWritable(HttpMessageNotWritableException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { ProblemDetail body = this.createProblemDetail(ex, status, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, status, request); } @Nullable @Override public ResponseEntity<Object> handleMethodValidationException(MethodValidationException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { ProblemDetail body = createProblemDetail(ex, status, ex.getLocalizedMessage(), null, null, request); return handleExceptionInternal(ex, body, headers, status, request); } /** * spring未管理的异常 */ @ExceptionHandler(ValidationException.class) public ResponseEntity<Object> handleValidationException(ValidationException ex, WebRequest request) { HttpHeaders headers = new HttpHeaders(); ProblemDetail body = this.createProblemDetail(ex, HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, HttpStatus.BAD_REQUEST, request); } @ExceptionHandler(ResponseStatusException.class) public ResponseEntity<Object> handleResponseStatusException(ResponseStatusException ex, WebRequest request) { HttpHeaders headers = new HttpHeaders(); ProblemDetail body = this.createProblemDetail(ex, ex.getStatusCode(), Optional.ofNullable(ex.getReason()).orElse(""), (String) null, (Object[]) null, request); return this.handleExceptionInternal(ex, body, headers, ex.getStatusCode(), request); } @ExceptionHandler(Exception.class) public ResponseEntity<Object> handleException2(Exception ex, WebRequest request) { HttpHeaders headers = new HttpHeaders(); ProblemDetail body = this.createProblemDetailControlLogLevel(ex, HttpStatus.INTERNAL_SERVER_ERROR, ex.getLocalizedMessage(), (String) null, (Object[]) null, request, "error"); return this.handleExceptionInternal(ex, body, headers, HttpStatus.INTERNAL_SERVER_ERROR, request); } @Override protected ProblemDetail createProblemDetail(Exception ex, HttpStatusCode status, String defaultDetail, @Nullable String detailMessageCode, @Nullable Object[] detailMessageArguments, WebRequest request) { return createProblemDetailControlLogLevel(ex, status, defaultDetail, detailMessageCode, detailMessageArguments, request, "warn"); } protected ProblemDetail createProblemDetailControlLogLevel(Exception ex, HttpStatusCode status, String defaultDetail, @Nullable String detailMessageCode, @Nullable Object[] detailMessageArguments, WebRequest request, String logLevel) { ProblemDetail problemDetail = super.createProblemDetail(ex, status, defaultDetail, detailMessageCode, detailMessageArguments, request); problemDetail.setProperty("exception", ex.getClass().getName()); problemDetail.setProperty("timestamp", ZonedDateTime.now().withZoneSameInstant(ZoneId.of("Asia/Shanghai")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"))); // problemDetail.setProperty("stackTrace", getStackTraceAsJsonArray(ex)); if (this.logger.isWarnEnabled() && "warn".equals(logLevel)) { this.logger.warn("发生warn级别异常: ", ex); } if (this.logger.isErrorEnabled() && "error".equals(logLevel)) { this.logger.warn("发生error级别异常: ", ex); } return problemDetail; } private List<String> getStackTraceAsJsonArray(Throwable throwable) { List<String> stackTrace = new ArrayList<>(); for (StackTraceElement element : throwable.getStackTrace()) { stackTrace.add(element.toString()); } return stackTrace; } }
|
也可以自定义异常继承 ErrorResponseException
其实就是将异常处理移到了声明类里面。
|----------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | java package com.zx.alice.exception; import org.springframework.http.HttpStatus; import org.springframework.http.ProblemDetail; import org.springframework.web.ErrorResponseException; import java.net.URI; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; public class UserNotFoundException extends ErrorResponseException { public UserNotFoundException(Long userId) { super(HttpStatus.NOT_FOUND, asProblemDetail("User with id " + userId + " not found"), null); } private static ProblemDetail asProblemDetail(String message) { ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, message); problemDetail.setTitle("User Not Found"); problemDetail.setType(URI.create("https://api.user.com/errors/not-found")); problemDetail.setProperty("exception", UserNotFoundException.class.getName()); problemDetail.setProperty("timestamp", ZonedDateTime.now().withZoneSameInstant(ZoneId.of("Asia/Shanghai")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"))); return problemDetail; } }
|
RestTemplate请求示例 {#resttemplate请求示例}
|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | java private final RestTemplate restTemplate; // 请求路径URI String url = "https://www.baidu.com"; // 构造请求头 HttpHeaders headers = new HttpHeaders(); headers.set("Content-Type", "application/json"); // 构造请求体 Map<String, String> map = new HashMap<>(); map.put("k1", "v1"); map.put("k2", "v2"); String body = new ObjectMapper().writeValueAsString(map); // 请求头+请求体 的请求实例 HttpEntity<String> httpEntity = new HttpEntity<>(body, headers); // 发送http请求 String string = restTemplate.getForObject(url, String.class, httpEntity); String string2 = restTemplate.postForObject(url, httpEntity, String.class);
|
TransactionTemplate事务 {#transactiontemplate事务}
|----------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | java @Slf4j @RequiredArgsConstructor public class 事务 { private final DataSourceTransactionManager transactionManager; @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = {Exception.class}) public Demo method() { TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); return transactionTemplate.execute(status -> { try { // 执行业务。。。 status.flush(); return new Demo(); } catch (Exception e) { status.setRollbackOnly(); log.error("===========业务执行失败!!!===========", e); return null; } }); } }
|
Spring使用@Qualifier来指定注入哪一个bean {#spring使用qualifier来指定注入哪一个bean}
|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 | java @Component public class MyComponent { // 使用@Qualifier来指定注入哪一个bean @Autowired @Qualifier("serviceOne") private MyService myService; public void execute() { myService.doSomething(); } }
|
|-------|----------------------------------------------------------------|
| 1 2 3 | java public interface MyService { void doSomething(); }
|
|-------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | java @Service("serviceOne") public class MyServiceImplOne implements MyService { @Override public void doSomething() { System.out.println("Doing something in MyServiceImplOne"); } } @Service("serviceTwo") public class MyServiceImplTwo implements MyService { @Override public void doSomething() { System.out.println("Doing something in MyServiceImplTwo"); } }
|
@Autowired注解 {#autowired注解}
字段注入的问题:
|-----|-------------------------------------------------------------|
| 1 2 | java @Autowired private CycleBService cycleBService;
|
- 对象的外部可见性(与Spring的IOC机制紧密耦合)
- 无法设置注入的对象为final,也无法注入静态变量
- 掩盖单一职责的设计思想
- 隐藏依赖性
- 无法对注入的属性进行安检
构造器注入适用于强制对象注入
构造方法器注入:构造方法注入需要使用@Lazy 注解来作用于循环依赖的属性
Setter注入适合可选对象注入
字段注入方式应该尽量避免,因为对象无法脱离容器独立运行(话虽这么说,但我还是字段注入用得多,因为方便啊)
三级缓存:
|----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | java public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { ... // 从上至下 分表代表这"三级缓存" private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); //一级缓存 private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); // 二级缓存 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 三级缓存 ... /** Names of beans that are currently in creation. */ // 这个缓存也十分重要:它表示bean创建过程中都会在里面呆着~ // 它在Bean开始创建时放值,创建完成时会将其移出~ private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); /** Names of beans that have already been created at least once. */ // 当这个Bean被创建完成后,会标记为这个 注意:这里是set集合 不会重复 // 至少被创建了一次的 都会放进这里~~~~ private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256)); }
|
- singletonObjects:用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用
- earlySingletonObjects:提前曝光的单例对象的cache,存放原始的 bean 对象(尚未填充属性),用于解决循环依赖
- singletonFactories:单例对象工厂的cache,存放 bean 工厂对象,用于解决循环依赖
ApplicationEvent事件使用-观察者、发布/订阅模式 {#applicationevent事件使用-观察者发布订阅模式}
事件/被观察者
|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | java @Getter public class SendEmailEvent extends ApplicationEvent { private final String from; private final String to; private final String cc; private final String subject; private final String text; public SendEmailEvent(Object source, String from, String to, String cc, String subject, String text) { super(source); this.from = from; this.to = to; this.cc = cc; this.subject = subject; this.text = text; } }
|
监听类实现方式1:实现ApplicationListener接口
|-------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 | java public class EmailServiceImpl1 implements ApplicationListener<SendEmailEvent> { @Override public void onApplicationEvent(SendEmailEvent event) { // 调用第三方邮件发送服务 } }
|
监听类实现方式2:@EventListener注解
|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 | java public class EmailServiceImpl2 { @EventListener(classes = {ContextRefreshedEvent.class, SendEmailEvent.class}) protected void testEvent() { // 调用第三方邮件发送服务 System.out.println("注解形式的事件刷新成功"); } }
|
发布事件
|-------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 | java private final ApplicationEventPublisher applicationEventPublisher; applicationEventPublisher.publishEvent(new SendEmailEvent(this, "from", "to", "cc", "subject", "text"));
|