springboot 은 Tomcat 용기 의 자체 작 동 프로 세 스 분석 을 바탕 으로 합 니 다.
12825 단어 springboottomcat시동
1.Spring 은 주 해 를 통 해 Bean 을 가 져 오 는 것 은 크게 네 가지 방식 으로 나 눌 수 있 습 니 다.우 리 는 주로 다음 과 같은 Import 의 두 가지 실현 방법 을 말 합 니 다.
1.ImportSerlector 인 터 페 이 스 를 실현 함으로써 Bean 로 딩 을 실현 합 니 다.
public class TestServiceImpl {
public void testImpl() {
System.out.println(" importSelector service");
}
}
public class TestService implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.ycdhz.service.TestServiceImpl"};
}
}
@Configuration
@Import(value = {TestService.class})
public class TestConfig {
}
public class TestController {
@Autowired
private TestServiceImpl testServiceImpl;
@RequestMapping("testImpl")
public String testTuling() {
testServiceImpl.testImpl();
return "Ok";
}
}
2.ImportSerlector 인 터 페 이 스 를 실현 함으로써 Bean 로드 를 실현 합 니 다.
public class TestService {
public TestService() {
System.out.println(" ImportBeanDefinitionRegistrar ");
}
}
public class TestImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// BeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(TestService.class);
// bean
registry.registerBeanDefinition("testService",beanDefinition);
}
}
@Configuration
@Import(TestImportBeanDefinitionRegistrar.class)
public class TestConfig {
}
2.Springboot 시작 과정 에서 자동 으로 조립 합 니 다.우 리 는 spring-boot-autoconfigure-2.0.6.RELEASE.jar 에서 Tomcat 의 관련 설정 을 검색 한 결과 두 개의 자동 조립 류 가 있 는데 각각 세 개의 맞 춤 형 기기(대상 을 대상 으로 하 는 단일 직책 원칙)와 한 개의 공장 류 가 포함 되 어 있 음 을 발견 했다.
2.1.TomcatWebServerFactory Customizer:맞 춤 형 Servlet 과 Reactive 서버 에서 통용 되 는 Tomcat 특정 기능.
public class TomcatWebServerFactoryCustomizer implements
WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory>, Ordered {
@Override
public void customize(ConfigurableTomcatWebServerFactory factory) {
ServerProperties properties = this.serverProperties;
ServerProperties.Tomcat tomcatProperties = properties.getTomcat();
PropertyMapper propertyMapper = PropertyMapper.get();
propertyMapper.from(tomcatProperties::getBasedir).whenNonNull()
.to(factory::setBaseDirectory);
propertyMapper.from(tomcatProperties::getBackgroundProcessorDelay).whenNonNull()
.as(Duration::getSeconds).as(Long::intValue)
.to(factory::setBackgroundProcessorDelay);
customizeRemoteIpValve(factory);
propertyMapper.from(tomcatProperties::getMaxThreads).when(this::isPositive)
.to((maxThreads) -> customizeMaxThreads(factory,
tomcatProperties.getMaxThreads()));
propertyMapper.from(tomcatProperties::getMinSpareThreads).when(this::isPositive)
.to((minSpareThreads) -> customizeMinThreads(factory, minSpareThreads));
propertyMapper.from(() -> determineMaxHttpHeaderSize()).when(this::isPositive)
.to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory,
maxHttpHeaderSize));
propertyMapper.from(tomcatProperties::getMaxHttpPostSize)
.when((maxHttpPostSize) -> maxHttpPostSize != 0)
.to((maxHttpPostSize) -> customizeMaxHttpPostSize(factory,
maxHttpPostSize));
propertyMapper.from(tomcatProperties::getAccesslog)
.when(ServerProperties.Tomcat.Accesslog::isEnabled)
.to((enabled) -> customizeAccessLog(factory));
propertyMapper.from(tomcatProperties::getUriEncoding).whenNonNull()
.to(factory::setUriEncoding);
propertyMapper.from(properties::getConnectionTimeout).whenNonNull()
.to((connectionTimeout) -> customizeConnectionTimeout(factory,
connectionTimeout));
propertyMapper.from(tomcatProperties::getMaxConnections).when(this::isPositive)
.to((maxConnections) -> customizeMaxConnections(factory, maxConnections));
propertyMapper.from(tomcatProperties::getAcceptCount).when(this::isPositive)
.to((acceptCount) -> customizeAcceptCount(factory, acceptCount));
customizeStaticResources(factory);
customizeErrorReportValve(properties.getError(), factory);
}
}
2.2,ServletWebServerFactory Customizer:WebServerFactory Customizer 는 ServerProperties 속성 을 Tomcat 웹 서버 에 적용 합 니 다.
public class ServletWebServerFactoryCustomizer implements
WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {
private final ServerProperties serverProperties;
public ServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
this.serverProperties = serverProperties;
}
@Override
public int getOrder() {
return 0;
}
@Override
public void customize(ConfigurableServletWebServerFactory factory) {
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
map.from(this.serverProperties::getPort).to(factory::setPort);
map.from(this.serverProperties::getAddress).to(factory::setAddress);
map.from(this.serverProperties.getServlet()::getContextPath)
.to(factory::setContextPath);
map.from(this.serverProperties.getServlet()::getApplicationDisplayName)
.to(factory::setDisplayName);
map.from(this.serverProperties.getServlet()::getSession).to(factory::setSession);
map.from(this.serverProperties::getSsl).to(factory::setSsl);
map.from(this.serverProperties.getServlet()::getJsp).to(factory::setJsp);
map.from(this.serverProperties::getCompression).to(factory::setCompression);
map.from(this.serverProperties::getHttp2).to(factory::setHttp2);
map.from(this.serverProperties::getServerHeader).to(factory::setServerHeader);
map.from(this.serverProperties.getServlet()::getContextParameters)
.to(factory::setInitParameters);
}
}
2.3,ServletWebServerFactory Customizer:WebServerFactory Customizer 는 ServerProperties 속성 을 Tomcat 웹 서버 에 적용 합 니 다.
public class TomcatServletWebServerFactoryCustomizer
implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>, Ordered {
private final ServerProperties serverProperties;
public TomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
this.serverProperties = serverProperties;
}
@Override
public void customize(TomcatServletWebServerFactory factory) {
ServerProperties.Tomcat tomcatProperties = this.serverProperties.getTomcat();
if (!ObjectUtils.isEmpty(tomcatProperties.getAdditionalTldSkipPatterns())) {
factory.getTldSkipPatterns()
.addAll(tomcatProperties.getAdditionalTldSkipPatterns());
}
if (tomcatProperties.getRedirectContextRoot() != null) {
customizeRedirectContextRoot(factory,
tomcatProperties.getRedirectContextRoot());
}
if (tomcatProperties.getUseRelativeRedirects() != null) {
customizeUseRelativeRedirects(factory,
tomcatProperties.getUseRelativeRedirects());
}
}
}
3.TomcatServletWebServerFactory 가 있 으 면 Spring 로 딩 의 입구 가 있 는 것 과 같 습 니 다.AbstractApplication Context\#onReFresh()를 통 해 IOC 용기 에서 tomcat 를 작 동 시 킨 다음 ioc 용기 의 다른 절 차 를 수행 합 니 다.
저 희 는 정지점 을 통 해 Tomcat 로 딩 의 전체 생명 주기 와 세 개의 맞 춤 형 기기 의 로 딩 과정 을 관찰 할 수 있 습 니 다.
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
File baseDir = (this.baseDirectory != null) ? this.baseDirectory
: createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
//
tomcat.getHost().setAutoDeploy(false);
// Tomcat
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
//
prepareContext(tomcat.getHost(), initializers);
//
return getTomcatWebServer(tomcat);
}
private void initialize() throws WebServerException {
TomcatWebServer.logger
.info("Tomcat initialized with port(s): " + getPortsDescription(false));
synchronized (this.monitor) {
try {
addInstanceIdToEngineName();
Context context = findContext();
context.addLifecycleListener((event) -> {
if (context.equals(event.getSource())
&& Lifecycle.START_EVENT.equals(event.getType())) {
// Remove service connectors so that protocol binding doesn't
// happen when the service is started.
removeServiceConnectors();
}
});
// Start the server to trigger initialization listeners
this.tomcat.start();
// We can re-throw failure exception directly in the main thread
rethrowDeferredStartupExceptions();
try {
ContextBindings.bindClassLoader(context, context.getNamingToken(),
getClass().getClassLoader());
}
catch (NamingException ex) {
// Naming is not enabled. Continue
}
// Unlike Jetty, all Tomcat threads are daemon threads. We create a
// blocking non-daemon to stop immediate shutdown
startDaemonAwaitThread();
}
catch (Exception ex) {
stopSilently();
throw new WebServerException("Unable to start embedded Tomcat", ex);
}
}
}
비고:이 과정 에서 우 리 는 Bean 의 생명 주 기 를 알 아야 합 니 다.Tomcat 의 세 개의 맞 춤 형 기 는 모두 Bean PostProcessors Registrar(Bean 백 엔 드 프로세서)과정 에서 불 러 옵 니 다.구조 방법-->Bean 백업 프로세서 Before-->InitialingBean-->init-method-->Bean 백업 프로세서 After
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Initialize the bean instance.
......
return exposedObject;
}
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//Bean Before
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//Bean After
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
총결산여기 서 springboot 이 Tomcat 용 기 를 바탕 으로 하 는 자체 시작 프로 세 스 분석 에 관 한 글 을 소개 합 니 다.더 많은 springboot tomcat 자체 시작 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin Springboot -- 파트 14 사용 사례 REST로 전환하여 POST로 JSON으로 전환前回 前回 前回 記事 の は は で で で で で で を 使っ 使っ 使っ て て て て て リクエスト を を 受け取り 、 reqeustbody で 、 その リクエスト の ボディ ボディ を を 受け取り 、 関数 内部 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.