Featured image of post 【合集】Spring常用代码

【合集】Spring常用代码

Spring Environment配置文件获取值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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
alarm:
  email:
    recipients: zhangSan,liSi,wangWu

分布式锁

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
@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

1
2
3
4
 <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
// 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)

访问地址:http://localhost:8080/swagger-ui/index.html

1
2
3
4
5
<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
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
# 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)

参考: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
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
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请求示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
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事务

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Component  
public class MyComponent {  
  
    // 使用@Qualifier来指定注入哪一个bean  
    @Autowired  
    @Qualifier("serviceOne")  
    private MyService myService;  
  
    public void execute() {  
        myService.doSomething();  
    }  
}
1
2
3
public interface MyService {
    void doSomething();
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@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注解

字段注入的问题:

1
2
@Autowired
private CycleBService cycleBService;
  1. 对象的外部可见性(与Spring的IOC机制紧密耦合)
  2. 无法设置注入的对象为final,也无法注入静态变量
  3. 掩盖单一职责的设计思想
  4. 隐藏依赖性
  5. 无法对注入的属性进行安检

构造器注入适用于强制对象注入

构造方法器注入:构造方法注入需要使用@Lazy 注解来作用于循环依赖的属性

Setter注入适合可选对象注入

字段注入方式应该尽量避免,因为对象无法脱离容器独立运行(话虽这么说,但我还是字段注入用得多,因为方便啊)

三级缓存:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
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));
}
  1. singletonObjects:用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用
  2. earlySingletonObjects:提前曝光的单例对象的cache,存放原始的 bean 对象(尚未填充属性),用于解决循环依赖
  3. singletonFactories:单例对象工厂的cache,存放 bean 工厂对象,用于解决循环依赖

ApplicationEvent事件使用-观察者、发布/订阅模式

【合集】Java设计模式

Java设计模式-观察者模式Observer

事件/被观察者

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
@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
public class EmailServiceImpl1 implements ApplicationListener<SendEmailEvent> {
    @Override
    public void onApplicationEvent(SendEmailEvent event) {
        // 调用第三方邮件发送服务
    }
}

监听类实现方式2:@EventListener注解

1
2
3
4
5
6
7
public class EmailServiceImpl2 {
    @EventListener(classes = {ContextRefreshedEvent.class, SendEmailEvent.class})
    protected void testEvent() {
        // 调用第三方邮件发送服务
        System.out.println("注解形式的事件刷新成功");
    }
}

发布事件

1
2
3
private final ApplicationEventPublisher applicationEventPublisher;

applicationEventPublisher.publishEvent(new SendEmailEvent(this, "from", "to", "cc", "subject", "text"));
皖ICP备2024056275号-1
发表了80篇文章 · 总计150.57k字
本站已稳定运行