gpt4 book ai didi

java - 为什么 Spring Boot DefaultFormattingConversionService 被创建但没有被引用?

转载 作者:行者123 更新时间:2023-12-01 13:01:55 29 4
gpt4 key购买 nike

我正在阅读 spring boot 源代码,当我阅读本文时,我很困惑。

/*
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.boot.autoconfigure;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.validation.Configuration;
import javax.validation.Validation;

import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.boot.context.event.SpringApplicationEvent;
import org.springframework.boot.context.logging.LoggingApplicationListener;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;

/**
* {@link ApplicationListener} to trigger early initialization in a background thread of
* time consuming tasks.
* <p>
* Set the {@link #IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME} system property to
* {@code true} to disable this mechanism and let such initialization happen in the
* foreground.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @author Artsiom Yudovin
* @since 1.3.0
*/
@Order(LoggingApplicationListener.DEFAULT_ORDER + 1)
public class BackgroundPreinitializer implements ApplicationListener<SpringApplicationEvent> {

/**
* System property that instructs Spring Boot how to run pre initialization. When the
* property is set to {@code true}, no pre-initialization happens and each item is
* initialized in the foreground as it needs to. When the property is {@code false}
* (default), pre initialization runs in a separate thread in the background.
* @since 2.1.0
*/
public static final String IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME = "spring.backgroundpreinitializer.ignore";

private static final AtomicBoolean preinitializationStarted = new AtomicBoolean(false);

private static final CountDownLatch preinitializationComplete = new CountDownLatch(1);

@Override
public void onApplicationEvent(SpringApplicationEvent event) {
if (!Boolean.getBoolean(IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME)
&& event instanceof ApplicationStartingEvent && multipleProcessors()
&& preinitializationStarted.compareAndSet(false, true)) {
performPreinitialization();
}
if ((event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent)
&& preinitializationStarted.get()) {
try {
preinitializationComplete.await();
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}

private boolean multipleProcessors() {
return Runtime.getRuntime().availableProcessors() > 1;
}

private void performPreinitialization() {
try {
Thread thread = new Thread(new Runnable() {

@Override
public void run() {
runSafely(new ConversionServiceInitializer());
runSafely(new ValidationInitializer());
runSafely(new MessageConverterInitializer());
runSafely(new JacksonInitializer());
runSafely(new CharsetInitializer());
preinitializationComplete.countDown();
}

public void runSafely(Runnable runnable) {
try {
runnable.run();
}
catch (Throwable ex) {
// Ignore
}
}

}, "background-preinit");
thread.start();
}
catch (Exception ex) {
// This will fail on GAE where creating threads is prohibited. We can safely
// continue but startup will be slightly slower as the initialization will now
// happen on the main thread.
preinitializationComplete.countDown();
}
}

/**
* Early initializer for Spring MessageConverters.
*/
private static class MessageConverterInitializer implements Runnable {

@Override
public void run() {
new AllEncompassingFormHttpMessageConverter();
}

}

/**
* Early initializer for javax.validation.
*/
private static class ValidationInitializer implements Runnable {

@Override
public void run() {
Configuration<?> configuration = Validation.byDefaultProvider().configure();
configuration.buildValidatorFactory().getValidator();
}

}

/**
* Early initializer for Jackson.
*/
private static class JacksonInitializer implements Runnable {

@Override
public void run() {
Jackson2ObjectMapperBuilder.json().build();
}

}

/**
* Early initializer for Spring's ConversionService.
*/
private static class ConversionServiceInitializer implements Runnable {

@Override
public void run() {
new DefaultFormattingConversionService();
}

}

private static class CharsetInitializer implements Runnable {

@Override
public void run() {
StandardCharsets.UTF_8.name();
}

}

}

这些线路:
    /**
* Early initializer for Spring's ConversionService.
*/
private static class ConversionServiceInitializer implements Runnable {

@Override
public void run() {
new DefaultFormattingConversionService();
}

}
为什么只是新建了一个 DefaultFormattingConversionService 对象,却没有赋值给任何引用。它有什么影响?
我读了一些源代码,但仍然很困惑。
谁能帮帮我,先谢谢了!
更新:
我调试了,但仍然找不到任何地方间接保留引用。
avatar

最佳答案

TL; 博士
你是对的。构造函数被调用并且对象本身永远不会被引用(直接)。您可以根据需要进行搜索,您不会发现这些创建的对象的任何用法。

为什么要这么做?
您引用的文件是由 Phil Webb 创建的在 2015 年,没有 Javadoc,但在提交消息中有详细描述:

Improve performance with BackgroundPreinitializer

Add a BackgroundPreinitializer to trigger early initialization in abackground thread of time consuming tasks. By moving certaininitialization tasks to background thread and triggering them earlywe can improve the critical path when the application starts. Forexample, Tomcat's MBeanFactory class parses several XML files whenfirst loaded. If we trigger the load in a background thread it completesbefore Tomcat actually needs to use it.

The initial set of initializers included with this commit are:

  • Tomcat MBeanFactory
  • javax.validation
  • Spring's AllEncompassingFormHttpMessageConverter

See gh-4252


引用的问题 gh-4252列出了一些性能测量并声称多线程预初始化的性能改进约为 13%。
您引用的方法,构建了 DefaultFormattingConversionService是在 #5182bc4f2 中引入的,也由先生。 webb 和 - 根据提交消息和引用的 issue (gh-6177) - 一点影响都没有 .

关于java - 为什么 Spring Boot DefaultFormattingConversionService 被创建但没有被引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62888900/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com