001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.autoconfigure.web.servlet; 018 019import javax.servlet.ServletRequest; 020 021import org.springframework.beans.BeansException; 022import org.springframework.beans.factory.BeanFactory; 023import org.springframework.beans.factory.BeanFactoryAware; 024import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 025import org.springframework.beans.factory.support.BeanDefinitionRegistry; 026import org.springframework.beans.factory.support.RootBeanDefinition; 027import org.springframework.boot.autoconfigure.AutoConfigureOrder; 028import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 029import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 030import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 031import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 032import org.springframework.boot.autoconfigure.web.ServerProperties; 033import org.springframework.boot.context.properties.EnableConfigurationProperties; 034import org.springframework.boot.web.server.ErrorPageRegistrarBeanPostProcessor; 035import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; 036import org.springframework.context.annotation.Bean; 037import org.springframework.context.annotation.Configuration; 038import org.springframework.context.annotation.Import; 039import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; 040import org.springframework.core.Ordered; 041import org.springframework.core.type.AnnotationMetadata; 042import org.springframework.util.ObjectUtils; 043 044/** 045 * {@link EnableAutoConfiguration Auto-configuration} for servlet web servers. 046 * 047 * @author Phillip Webb 048 * @author Dave Syer 049 * @author Ivan Sopov 050 * @author Brian Clozel 051 * @author Stephane Nicoll 052 */ 053@Configuration 054@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) 055@ConditionalOnClass(ServletRequest.class) 056@ConditionalOnWebApplication(type = Type.SERVLET) 057@EnableConfigurationProperties(ServerProperties.class) 058@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, 059 ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, 060 ServletWebServerFactoryConfiguration.EmbeddedJetty.class, 061 ServletWebServerFactoryConfiguration.EmbeddedUndertow.class }) 062public class ServletWebServerFactoryAutoConfiguration { 063 064 @Bean 065 public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer( 066 ServerProperties serverProperties) { 067 return new ServletWebServerFactoryCustomizer(serverProperties); 068 } 069 070 @Bean 071 @ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat") 072 public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer( 073 ServerProperties serverProperties) { 074 return new TomcatServletWebServerFactoryCustomizer(serverProperties); 075 } 076 077 /** 078 * Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via 079 * {@link ImportBeanDefinitionRegistrar} for early registration. 080 */ 081 public static class BeanPostProcessorsRegistrar 082 implements ImportBeanDefinitionRegistrar, BeanFactoryAware { 083 084 private ConfigurableListableBeanFactory beanFactory; 085 086 @Override 087 public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 088 if (beanFactory instanceof ConfigurableListableBeanFactory) { 089 this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; 090 } 091 } 092 093 @Override 094 public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, 095 BeanDefinitionRegistry registry) { 096 if (this.beanFactory == null) { 097 return; 098 } 099 registerSyntheticBeanIfMissing(registry, 100 "webServerFactoryCustomizerBeanPostProcessor", 101 WebServerFactoryCustomizerBeanPostProcessor.class); 102 registerSyntheticBeanIfMissing(registry, 103 "errorPageRegistrarBeanPostProcessor", 104 ErrorPageRegistrarBeanPostProcessor.class); 105 } 106 107 private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, 108 String name, Class<?> beanClass) { 109 if (ObjectUtils.isEmpty( 110 this.beanFactory.getBeanNamesForType(beanClass, true, false))) { 111 RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass); 112 beanDefinition.setSynthetic(true); 113 registry.registerBeanDefinition(name, beanDefinition); 114 } 115 } 116 117 } 118 119}