mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
Polish and Fixup
Polish and fixup: - Ordered auto-configuration - @ConditionalOnBean default on @Bean methods - Improved separation of auto-configure classes - Consistent naming - Javadoc, code formatting and tests
This commit is contained in:
parent
2f84df66b6
commit
dd69d0f660
@ -23,6 +23,8 @@ import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for {@link MessageSource}.
|
||||
@ -31,6 +33,7 @@ import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(MessageSource.class)
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class MessageSourceAutoConfiguration {
|
||||
|
||||
@Value("${spring.messages.basename:messages}")
|
||||
|
@ -16,11 +16,14 @@
|
||||
|
||||
package org.springframework.bootstrap.autoconfigure;
|
||||
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
|
||||
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for
|
||||
@ -30,9 +33,11 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class PropertyPlaceholderAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(
|
||||
ApplicationContext context) {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
|
@ -25,7 +25,7 @@ import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.bootstrap.context.annotation.AutoConfigurationUtils;
|
||||
import org.springframework.bootstrap.autoconfigure.AutoConfigurationUtils;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
|
@ -206,7 +206,6 @@ public class DataSourceAutoConfiguration {
|
||||
}
|
||||
return super.matches(context, metadata);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static abstract class NonEmbeddedDatabaseCondition implements Condition {
|
||||
|
@ -25,7 +25,6 @@ import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
|
||||
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.orm.jpa.JpaVendorAdapter;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
@ -42,7 +41,6 @@ import org.springframework.util.StringUtils;
|
||||
@Configuration
|
||||
@ConditionalOnClass(HibernateEntityManager.class)
|
||||
@EnableTransactionManagement
|
||||
@Import(JpaComponentScanDetector.class)
|
||||
public class HibernateJpaAutoConfiguration extends JpaAutoConfiguration {
|
||||
|
||||
public static enum DDLAUTO {
|
||||
|
@ -27,8 +27,8 @@ import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.bootstrap.autoconfigure.AutoConfigurationUtils;
|
||||
import org.springframework.bootstrap.autoconfigure.jdbc.EmbeddedDatabaseConfiguration;
|
||||
import org.springframework.bootstrap.context.annotation.AutoConfigurationUtils;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnBean;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
|
||||
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
|
||||
|
@ -27,6 +27,8 @@ import nz.net.ultraq.web.thymeleaf.LayoutDialect;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.bootstrap.autoconfigure.web.WebMvcAutoConfiguration;
|
||||
import org.springframework.bootstrap.context.annotation.AutoConfigureAfter;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingClass;
|
||||
@ -49,6 +51,7 @@ import org.thymeleaf.templateresolver.TemplateResolver;
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(SpringTemplateEngine.class)
|
||||
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
|
||||
public class ThymeleafAutoConfiguration {
|
||||
|
||||
@Configuration
|
||||
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.bootstrap.autoconfigure.web;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.Servlet;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
|
||||
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
|
||||
import org.springframework.bootstrap.context.embedded.ConfigurableEmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for
|
||||
* {@link EmbeddedServletContainerCustomizer}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Servlet.class, EmbeddedServletContainerCustomizer.class })
|
||||
public class EmbeddedContainerCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
public BeanPostProcessor embeddedContainerCustomizerBeanPostProcessor(
|
||||
ListableBeanFactory beanFactory) {
|
||||
// Look these up, not autowired because we don't want the ones from the parent
|
||||
// context
|
||||
Collection<EmbeddedServletContainerCustomizer> customizers = beanFactory
|
||||
.getBeansOfType(EmbeddedServletContainerCustomizer.class).values();
|
||||
return new EmbeddedContainerCustomizerBeanPostProcessor(customizers);
|
||||
}
|
||||
|
||||
private static final class EmbeddedContainerCustomizerBeanPostProcessor implements
|
||||
BeanPostProcessor {
|
||||
|
||||
private List<EmbeddedServletContainerCustomizer> customizers;
|
||||
|
||||
public EmbeddedContainerCustomizerBeanPostProcessor(
|
||||
Collection<EmbeddedServletContainerCustomizer> customizers) {
|
||||
final List<EmbeddedServletContainerCustomizer> list = new ArrayList<EmbeddedServletContainerCustomizer>(
|
||||
customizers);
|
||||
Collections.sort(list, new AnnotationAwareOrderComparator());
|
||||
this.customizers = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (bean instanceof ConfigurableEmbeddedServletContainerFactory) {
|
||||
ConfigurableEmbeddedServletContainerFactory factory = (ConfigurableEmbeddedServletContainerFactory) bean;
|
||||
for (EmbeddedServletContainerCustomizer customizer : this.customizers) {
|
||||
customizer.customize(factory);
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -24,47 +24,59 @@ import org.eclipse.jetty.util.Loader;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
|
||||
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerCustomizer;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.context.embedded.ServletContextInitializer;
|
||||
import org.springframework.bootstrap.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for an embedded servlet container.
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for an embedded servlet containers.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class EmbeddedContainerConfiguration implements ImportSelector {
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class EmbeddedServletContainerAutoConfiguration {
|
||||
|
||||
@Override
|
||||
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
||||
// Don't import the classes directly because that might trigger loading them - use
|
||||
// an import selector and the class name instead
|
||||
return new String[] { ServerPropertiesConfiguration.class.getName(),
|
||||
EmbeddedJettyAutoConfiguration.class.getName(),
|
||||
EmbeddedTomcatAutoConfiguration.class.getName() };
|
||||
/**
|
||||
* Support {@link EmbeddedServletContainerCustomizerBeanPostProcessor} to apply
|
||||
* {@link EmbeddedServletContainerCustomizer}s.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = EmbeddedServletContainerCustomizerBeanPostProcessor.class, considerHierarchy = false)
|
||||
public EmbeddedServletContainerCustomizerBeanPostProcessor embeddedServletContainerCustomizerBeanPostProcessor() {
|
||||
return new EmbeddedServletContainerCustomizerBeanPostProcessor();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Servlet.class, Server.class, Loader.class })
|
||||
@ConditionalOnMissingBean(EmbeddedServletContainerFactory.class)
|
||||
public static class EmbeddedJettyAutoConfiguration {
|
||||
/**
|
||||
* Add the {@link DispatcherServlet} unless the user has defined their own
|
||||
* {@link ServletContextInitializer}s.
|
||||
*/
|
||||
@ConditionalOnClass(DispatcherServlet.class)
|
||||
public static class DispatcherServletConfiguration {
|
||||
|
||||
@Bean
|
||||
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
|
||||
return new JettyEmbeddedServletContainerFactory();
|
||||
@ConditionalOnMissingBean(value = { ServletContextInitializer.class,
|
||||
Servlet.class }, considerHierarchy = false)
|
||||
public DispatcherServlet dispatcherServlet() {
|
||||
return new DispatcherServlet();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested configuration for if Tomcat is being used.
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Servlet.class, Tomcat.class })
|
||||
@ConditionalOnMissingBean(EmbeddedServletContainerFactory.class)
|
||||
public static class EmbeddedTomcatAutoConfiguration {
|
||||
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, considerHierarchy = false)
|
||||
public static class EmbeddedTomcat {
|
||||
|
||||
@Bean
|
||||
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
|
||||
@ -73,4 +85,19 @@ public class EmbeddedContainerConfiguration implements ImportSelector {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested configuration if Jetty is being used.
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Servlet.class, Server.class, Loader.class })
|
||||
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, considerHierarchy = false)
|
||||
public static class EmbeddedJetty {
|
||||
|
||||
@Bean
|
||||
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
|
||||
return new JettyEmbeddedServletContainerFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -18,21 +18,23 @@ package org.springframework.bootstrap.autoconfigure.web;
|
||||
|
||||
import org.apache.catalina.valves.AccessLogValve;
|
||||
import org.apache.catalina.valves.RemoteIpValve;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
|
||||
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
|
||||
import org.springframework.bootstrap.context.annotation.EnableConfigurationProperties;
|
||||
import org.springframework.bootstrap.context.embedded.ConfigurableEmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerCustomizer;
|
||||
import org.springframework.bootstrap.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.properties.ServerProperties;
|
||||
import org.springframework.bootstrap.properties.ServerProperties.Tomcat;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link EmbeddedServletContainerCustomizer} that configures the
|
||||
* {@link EnableAutoConfiguration Auto-configuration} that configures the
|
||||
* {@link ConfigurableEmbeddedServletContainerFactory} from a {@link ServerProperties}
|
||||
* bean.
|
||||
*
|
||||
@ -40,22 +42,28 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
public class ServerPropertiesConfiguration implements EmbeddedServletContainerCustomizer {
|
||||
public class ServerPropertiesAutoConfiguration implements
|
||||
EmbeddedServletContainerCustomizer, ApplicationContextAware {
|
||||
|
||||
@Autowired
|
||||
private BeanFactory beanFactory;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@ConditionalOnMissingBean(ServerProperties.class)
|
||||
@Bean(name = "org.springframework.bootstrap.properties.ServerProperties")
|
||||
@ConditionalOnMissingBean
|
||||
public ServerProperties serverProperties() {
|
||||
return new ServerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(ConfigurableEmbeddedServletContainerFactory factory) {
|
||||
|
||||
// Need to do a look up here to make it lazy
|
||||
ServerProperties server = this.beanFactory.getBean(ServerProperties.class);
|
||||
ServerProperties server = this.applicationContext.getBean(ServerProperties.class);
|
||||
|
||||
factory.setPort(server.getPort());
|
||||
factory.setAddress(server.getAddress());
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.bootstrap.autoconfigure.web;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.servlet.Servlet;
|
||||
@ -24,14 +25,15 @@ import javax.servlet.Servlet;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.bootstrap.autoconfigure.web.WebMvcAutoConfiguration.WebMvcConfiguration;
|
||||
import org.springframework.bootstrap.context.annotation.AutoConfigureAfter;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnBean;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
|
||||
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.GenericConverter;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
@ -56,20 +58,20 @@ import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebMvc Web MVC}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class })
|
||||
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
|
||||
WebMvcConfigurerAdapter.class })
|
||||
@ConditionalOnMissingBean({ HandlerAdapter.class, HandlerMapping.class })
|
||||
@Import(WebMvcConfiguration.class)
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 10)
|
||||
@AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class)
|
||||
public class WebMvcAutoConfiguration {
|
||||
|
||||
/**
|
||||
* Nested configuration used because {@code @EnableWebMvc} will add HandlerAdapter and
|
||||
* HandlerMapping, causing the condition to fail and the additional DispatcherServlet
|
||||
* bean never to be registered if it were declared directly.
|
||||
*/
|
||||
// Defined as a nested config to ensure WebMvcConfigurerAdapter it not read when not
|
||||
// on the classpath
|
||||
@EnableWebMvc
|
||||
public static class WebMvcConfiguration extends WebMvcConfigurerAdapter {
|
||||
public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private ListableBeanFactory beanFactory;
|
||||
@ -91,11 +93,6 @@ public class WebMvcAutoConfiguration {
|
||||
return resolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DispatcherServlet dispatcherServlet() {
|
||||
return new DispatcherServlet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureDefaultServletHandling(
|
||||
DefaultServletHandlerConfigurer configurer) {
|
||||
@ -104,22 +101,27 @@ public class WebMvcAutoConfiguration {
|
||||
|
||||
@Override
|
||||
public void addFormatters(FormatterRegistry registry) {
|
||||
for (Converter<?, ?> converter : this.beanFactory.getBeansOfType(
|
||||
Converter.class).values()) {
|
||||
for (Converter<?, ?> converter : getBeansOfType(Converter.class)) {
|
||||
registry.addConverter(converter);
|
||||
}
|
||||
for (GenericConverter converter : this.beanFactory.getBeansOfType(
|
||||
GenericConverter.class).values()) {
|
||||
|
||||
for (GenericConverter converter : getBeansOfType(GenericConverter.class)) {
|
||||
registry.addConverter(converter);
|
||||
}
|
||||
for (Formatter<?> formatter : this.beanFactory
|
||||
.getBeansOfType(Formatter.class).values()) {
|
||||
|
||||
for (Formatter<?> formatter : getBeansOfType(Formatter.class)) {
|
||||
registry.addFormatter(formatter);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> Collection<T> getBeansOfType(Class<T> type) {
|
||||
return this.beanFactory.getBeansOfType(type).values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
// FIXME exposing the root classpath is a security risk
|
||||
// eg http://localhost:8080/org/springframework/bootstrap/Banner.class
|
||||
registry.addResourceHandler("/resources/**").addResourceLocations("/")
|
||||
.addResourceLocations("classpath:/META-INF/resources/")
|
||||
.addResourceLocations("classpath:/resources/")
|
||||
@ -130,26 +132,25 @@ public class WebMvcAutoConfiguration {
|
||||
.addResourceLocations("classpath:/");
|
||||
}
|
||||
|
||||
}
|
||||
@Configuration
|
||||
public static class FaviconConfiguration {
|
||||
|
||||
@Configuration
|
||||
public static class FaviconConfiguration {
|
||||
@Bean
|
||||
public SimpleUrlHandlerMapping faviconHandlerMapping() {
|
||||
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
|
||||
mapping.setOrder(Integer.MIN_VALUE + 1);
|
||||
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
|
||||
faviconRequestHandler()));
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SimpleUrlHandlerMapping faviconHandlerMapping() {
|
||||
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
|
||||
mapping.setOrder(Integer.MIN_VALUE + 1);
|
||||
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
|
||||
faviconRequestHandler()));
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected ResourceHttpRequestHandler faviconRequestHandler() {
|
||||
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
|
||||
requestHandler.setLocations(Arrays.<Resource> asList(new ClassPathResource(
|
||||
"/")));
|
||||
return requestHandler;
|
||||
@Bean
|
||||
protected ResourceHttpRequestHandler faviconRequestHandler() {
|
||||
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
|
||||
requestHandler.setLocations(Arrays
|
||||
.<Resource> asList(new ClassPathResource("/")));
|
||||
return requestHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,12 +21,12 @@ import java.util.Map;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Thin wrapper for Jackson 2 {@link ObjectMapper}.
|
||||
* Thin wrapper to adapt Jackson 2 {@link ObjectMapper} to {@link JsonParser}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @see JsonParserFactory
|
||||
*/
|
||||
public class JacksonParser implements JsonParser {
|
||||
public class JacksonJsonParser implements JsonParser {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> parseMap(String json) {
|
@ -19,13 +19,28 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* Parser that can read JSON formatted strings into {@link Map}s or {@link List}s.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @see JsonParserFactory
|
||||
* @see SimpleJsonParser
|
||||
* @see JacksonJsonParser
|
||||
* @see YamlJsonParser
|
||||
*/
|
||||
public interface JsonParser {
|
||||
|
||||
/**
|
||||
* Parse the specified JSON string into a Map.
|
||||
* @param json the JSON to parse
|
||||
* @return the parsed JSON as a map
|
||||
*/
|
||||
Map<String, Object> parseMap(String json);
|
||||
|
||||
/**
|
||||
* Parse the specified JSON string into a List.
|
||||
* @param json the JSON to parse
|
||||
* @return the parsed JSON as a list
|
||||
*/
|
||||
List<Object> parseList(String json);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.bootstrap.config;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Factory to create a {@link JsonParser}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @see JacksonJsonParser
|
||||
* @see YamlJsonParser
|
||||
* @see SimpleJsonParser
|
||||
*/
|
||||
public class JsonParserFactory {
|
||||
|
||||
/**
|
||||
* Static factory for the "best" JSON parser available on the classpath. Tries Jackson
|
||||
* (2), then Snake YAML, and then falls back to the {@link SimpleJsonParser}.
|
||||
*
|
||||
* @return a {@link JsonParser}
|
||||
*/
|
||||
public static JsonParser getJsonParser() {
|
||||
if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", null)) {
|
||||
return new JacksonJsonParser();
|
||||
}
|
||||
if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
|
||||
return new YamlJsonParser();
|
||||
}
|
||||
return new SimpleJsonParser();
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.bootstrap.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -21,7 +22,6 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@ -30,29 +30,11 @@ import org.springframework.util.StringUtils;
|
||||
* so users will probably prefer to have a library handle things instead (Jackson or Snake
|
||||
* YAML are supported).
|
||||
*
|
||||
* @see #instance()
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @see JsonParserFactory
|
||||
*/
|
||||
public class SimpleJsonParser implements JsonParser {
|
||||
|
||||
/**
|
||||
* Static factory for the "best" JSON parser available on the classpath. Tries Jackson
|
||||
* (2), then Snake YAML, and then falls back to the {@link SimpleJsonParser}.
|
||||
*
|
||||
* @return a {@link JsonParser}
|
||||
*/
|
||||
public static JsonParser instance() {
|
||||
if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
|
||||
return new YamlParser();
|
||||
}
|
||||
if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", null)) {
|
||||
return new JacksonParser();
|
||||
}
|
||||
return new SimpleJsonParser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> parseMap(String json) {
|
||||
if (json.startsWith("{")) {
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.bootstrap.config;
|
||||
|
||||
import java.util.List;
|
||||
@ -21,12 +22,12 @@ import java.util.Map;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* Thin wrapper for Snake {@link Yaml}.
|
||||
* Thin wrapper to adapt Snake {@link Yaml} to {@link JsonParser}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @see JsonParserFactory
|
||||
*/
|
||||
public class YamlParser implements JsonParser {
|
||||
public class YamlJsonParser implements JsonParser {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> parseMap(String json) {
|
@ -31,6 +31,7 @@ import org.springframework.context.annotation.Conditional;
|
||||
* not already contained in the {@link BeanFactory}, and throws an exception otherwise.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @see ConditionalOnMissingBean
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ -52,4 +53,9 @@ public @interface AssertMissingBean {
|
||||
*/
|
||||
String[] name() default {};
|
||||
|
||||
/**
|
||||
* If the application context hierarchy (parent contexts) should be considered.
|
||||
*/
|
||||
boolean considerHierarchy() default true;
|
||||
|
||||
}
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.bootstrap.context.annotation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
@ -35,11 +37,12 @@ class AssertMissingBeanCondition extends OnMissingBeanCondition {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
boolean result = super.matches(context, metadata);
|
||||
protected boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata,
|
||||
List<String> beanClasses, List<String> beanNames) throws LinkageError {
|
||||
boolean result = super.matches(context, metadata, beanClasses, beanNames);
|
||||
if (!result) {
|
||||
throw new BeanCreationException("Found existing bean for classes="
|
||||
+ getBeanClasses() + " and names=" + getBeanNames());
|
||||
+ beanClasses + " and names=" + beanNames);
|
||||
}
|
||||
return result;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.bootstrap.context.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
|
||||
/**
|
||||
* Convenience class for storing base packages during component scan, for reference later
|
||||
* (e.g. by JPA entity scanner).
|
||||
*
|
||||
* @author Phil Webb
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public abstract class AutoConfigurationUtils {
|
||||
|
||||
private static String BASE_PACKAGES_BEAN = AutoConfigurationUtils.class.getName()
|
||||
+ ".basePackages";
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<String> getBasePackages(BeanFactory beanFactory) {
|
||||
try {
|
||||
return beanFactory.getBean(BASE_PACKAGES_BEAN, List.class);
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
public static void storeBasePackages(ConfigurableListableBeanFactory beanFactory,
|
||||
List<String> basePackages) {
|
||||
if (!beanFactory.containsBean(BASE_PACKAGES_BEAN)) {
|
||||
beanFactory.registerSingleton(BASE_PACKAGES_BEAN, new ArrayList<String>(
|
||||
basePackages));
|
||||
} else {
|
||||
List<String> packages = getBasePackages(beanFactory);
|
||||
for (String pkg : basePackages) {
|
||||
if (packages.contains(pkg)) {
|
||||
packages.add(pkg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.bootstrap.context.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.apache.catalina.core.ApplicationContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
|
||||
/**
|
||||
* {@link Conditional} that only matches specific {@link ApplicationContext}s and that can
|
||||
* optionally create them.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Conditional(OnApplicationContextCondition.class)
|
||||
public @interface ConditionalOnApplicationContext {
|
||||
|
||||
// FIXME complete of delete this
|
||||
|
||||
/**
|
||||
* The ID of the application context.
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
// FIXME Strategy Interface Class, eg ApplicationContextCondition
|
||||
// condition=SomethingSpecific.class
|
||||
|
||||
boolean createIfMissing() default false;
|
||||
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.bootstrap.context.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
|
@ -22,9 +22,15 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Enable support for {@link ConfigurationProperties} annotated beans.
|
||||
* {@link ConfigurationProperties} beans can be registered in the standard way (for
|
||||
* example using {@link Bean @Bean} methods) or, for convenience, can be specified
|
||||
* directly on this annotation.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@ -33,7 +39,10 @@ import org.springframework.context.annotation.Import;
|
||||
@Import(EnableConfigurationPropertiesImportSelector.class)
|
||||
public @interface EnableConfigurationProperties {
|
||||
|
||||
/**
|
||||
* Convenient way to quickly register {@link ConfigurationProperties} beans with
|
||||
* Spring. Standard Spring Beans will also be scanned regardless of this value.
|
||||
*/
|
||||
Class<?>[] value() default {};
|
||||
|
||||
// FIXME Javadoc
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.bootstrap.context.annotation;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class OnApplicationContextCondition implements Condition {
|
||||
|
||||
// FIXME complete or delete
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
AnnotationAttributes attributes = AnnotationAttributes
|
||||
.fromMap(metadata
|
||||
.getAnnotationAttributes(ConditionalOnApplicationContext.class
|
||||
.getName()));
|
||||
String id = (String) attributes.get("value");
|
||||
boolean createIfMissing = attributes.getBoolean("createIfMissing");
|
||||
ApplicationContext applicationContext = context.getApplicationContext();
|
||||
|
||||
if (applicationContext != null) {
|
||||
if (StringUtils.hasLength(id) && applicationContext.getId().equals(id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (createIfMissing) {
|
||||
registerCreate(applicationContext, metadata);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param applicationContext
|
||||
* @param metadata
|
||||
*/
|
||||
private void registerCreate(ApplicationContext applicationContext,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
Assert.notNull(applicationContext,
|
||||
"Unable to create ApplicationContext from @ConditionalOnApplicationContext");
|
||||
}
|
||||
}
|
@ -78,4 +78,5 @@ class OnMissingClassCondition implements Condition {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME merge with OnClassCondition
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ package org.springframework.bootstrap.context.embedded;
|
||||
* than injecting them with <code>@Autowired</code>.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @see EmbeddedServletContainerCustomizerBeanPostProcessor
|
||||
*/
|
||||
public interface EmbeddedServletContainerCustomizer {
|
||||
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.bootstrap.context.embedded;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} that apply all {@link EmbeddedServletContainerCustomizer}s
|
||||
* from the bean factory to {@link ConfigurableEmbeddedServletContainerFactory} beans.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class EmbeddedServletContainerCustomizerBeanPostProcessor implements
|
||||
BeanPostProcessor, ApplicationContextAware {
|
||||
|
||||
// FIXME should we register this by default, Javadoc in
|
||||
// EmbeddedServletContainerCustomizer suggests so
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private List<EmbeddedServletContainerCustomizer> customizers;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (bean instanceof ConfigurableEmbeddedServletContainerFactory) {
|
||||
postProcessBeforeInitialization((ConfigurableEmbeddedServletContainerFactory) bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
private void postProcessBeforeInitialization(
|
||||
ConfigurableEmbeddedServletContainerFactory bean) {
|
||||
for (EmbeddedServletContainerCustomizer customizer : getCustomizers()) {
|
||||
customizer.customize(bean);
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<EmbeddedServletContainerCustomizer> getCustomizers() {
|
||||
if (this.customizers == null) {
|
||||
// Look up does not include the parent context
|
||||
this.customizers = new ArrayList<EmbeddedServletContainerCustomizer>(
|
||||
this.applicationContext.getBeansOfType(
|
||||
EmbeddedServletContainerCustomizer.class).values());
|
||||
Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE);
|
||||
this.customizers = Collections.unmodifiableList(this.customizers);
|
||||
}
|
||||
return this.customizers;
|
||||
}
|
||||
|
||||
}
|
@ -34,13 +34,12 @@ import javax.servlet.ServletException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.ContextLoader;
|
||||
import org.springframework.web.context.ContextLoaderListener;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
@ -153,17 +152,22 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext
|
||||
* @return a {@link EmbeddedServletContainerFactory} (never {@code null})
|
||||
*/
|
||||
protected EmbeddedServletContainerFactory getEmbeddedServletContainerFactory() {
|
||||
try {
|
||||
return getBeanFactory().getBean(EmbeddedServletContainerFactory.class);
|
||||
} catch (NoUniqueBeanDefinitionException ex) {
|
||||
throw new ApplicationContextException(
|
||||
"Unable to start EmbeddedWebApplicationContext due to multiple "
|
||||
+ "EmbeddedServletContainerFactory beans.", ex);
|
||||
} catch (NoSuchBeanDefinitionException ex) {
|
||||
// Use bean names so that we don't consider the hierarchy
|
||||
String[] beanNames = getBeanFactory().getBeanNamesForType(
|
||||
EmbeddedServletContainerFactory.class);
|
||||
if (beanNames.length == 0) {
|
||||
throw new ApplicationContextException(
|
||||
"Unable to start EmbeddedWebApplicationContext due to missing "
|
||||
+ "EmbeddedServletContainerFactory bean.", ex);
|
||||
+ "EmbeddedServletContainerFactory bean.");
|
||||
}
|
||||
if (beanNames.length > 1) {
|
||||
throw new ApplicationContextException(
|
||||
"Unable to start EmbeddedWebApplicationContext due to multiple "
|
||||
+ "EmbeddedServletContainerFactory beans : "
|
||||
+ StringUtils.arrayToCommaDelimitedString(beanNames));
|
||||
}
|
||||
return getBeanFactory().getBean(beanNames[0],
|
||||
EmbeddedServletContainerFactory.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.bootstrap.context.initializer;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.Ordered;
|
||||
@ -23,6 +24,25 @@ import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link ApplicationContextInitializer} that set the Spring
|
||||
* {@link ApplicationContext#getId() ApplicationContext ID}. The following environment
|
||||
* properties will be consulted to create the ID:
|
||||
* <ul>
|
||||
* <li>spring.application.name</li>
|
||||
* <li>vcap.application.name</li>
|
||||
* <li>spring.config.name</li>
|
||||
* </ul>
|
||||
* If no property is set the ID 'application' will be used.
|
||||
*
|
||||
* <p>
|
||||
* In addition the following environment properties will be consulted to append a relevant
|
||||
* port or index:
|
||||
*
|
||||
* <ul>
|
||||
* <li>spring.application.index</li>
|
||||
* <li>vcap.application.instance_index</li>
|
||||
* <li>PORT</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ -58,6 +78,7 @@ public class ContextIdApplicationContextInitializer implements
|
||||
if (index >= 0) {
|
||||
name = name + ":" + index;
|
||||
} else {
|
||||
// FIXME do we want this
|
||||
String profiles = StringUtils.arrayToCommaDelimitedString(environment
|
||||
.getActiveProfiles());
|
||||
if (StringUtils.hasText(profiles)) {
|
||||
|
@ -24,7 +24,7 @@ import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.bootstrap.config.JsonParser;
|
||||
import org.springframework.bootstrap.config.SimpleJsonParser;
|
||||
import org.springframework.bootstrap.config.JsonParserFactory;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.Ordered;
|
||||
@ -89,7 +89,7 @@ public class VcapApplicationContextInitializer implements
|
||||
|
||||
private int order = Integer.MIN_VALUE + 11;
|
||||
|
||||
private JsonParser parser = SimpleJsonParser.instance();
|
||||
private JsonParser parser = JsonParserFactory.getJsonParser();
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
|
@ -35,6 +35,8 @@ import org.apache.maven.plugins.shade.resource.ResourceTransformer;
|
||||
*/
|
||||
public class PropertiesMergingResourceTransformer implements ResourceTransformer {
|
||||
|
||||
// FIXME move out of core
|
||||
|
||||
String resource; // Set this in pom configuration with <resource>...</resource>
|
||||
|
||||
private Properties data = new Properties();
|
||||
|
@ -1,18 +1,21 @@
|
||||
# Auto Configure
|
||||
org.springframework.bootstrap.context.annotation.EnableAutoConfiguration=\
|
||||
org.springframework.bootstrap.autoconfigure.PropertyPlaceholderAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.MessageSourceAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.jdbc.DataSourceAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.data.JpaRepositoriesAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.PropertyPlaceholderAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.batch.BatchAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.data.JpaRepositoriesAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.jdbc.DataSourceAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.web.EmbeddedContainerConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.web.EmbeddedContainerCustomizerConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.web.ServerPropertiesAutoConfiguration,\
|
||||
org.springframework.bootstrap.autoconfigure.web.WebMvcAutoConfiguration
|
||||
|
||||
# Application Context Initializers
|
||||
org.springframework.context.ApplicationContextInitializer=\
|
||||
org.springframework.bootstrap.context.initializer.ConfigFileApplicationContextInitializer,\
|
||||
org.springframework.bootstrap.context.initializer.LoggingApplicationContextInitializer,\
|
||||
org.springframework.bootstrap.context.initializer.VcapApplicationContextInitializer,\
|
||||
org.springframework.bootstrap.context.initializer.ContextIdApplicationContextInitializer,\
|
||||
org.springframework.bootstrap.context.initializer.EnvironmentDelegateApplicationContextInitializer
|
||||
org.springframework.bootstrap.context.initializer.EnvironmentDelegateApplicationContextInitializer,\
|
||||
org.springframework.bootstrap.context.initializer.LoggingApplicationContextInitializer,\
|
||||
org.springframework.bootstrap.context.initializer.VcapApplicationContextInitializer
|
||||
|
@ -24,6 +24,7 @@ import org.springframework.bootstrap.autoconfigure.data.test.City;
|
||||
import org.springframework.bootstrap.autoconfigure.data.test.CityRepository;
|
||||
import org.springframework.bootstrap.autoconfigure.jdbc.EmbeddedDatabaseConfiguration;
|
||||
import org.springframework.bootstrap.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.bootstrap.context.annotation.ComponentScanDetectorConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -42,6 +43,7 @@ public class JpaRepositoriesAutoConfigurationTests {
|
||||
public void testDefaultRepositoryConfiguration() throws Exception {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(TestConfiguration.class,
|
||||
ComponentScanDetectorConfiguration.class,
|
||||
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
|
||||
JpaRepositoriesAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
|
@ -23,6 +23,7 @@ import org.springframework.bootstrap.autoconfigure.PropertyPlaceholderAutoConfig
|
||||
import org.springframework.bootstrap.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
||||
import org.springframework.bootstrap.autoconfigure.jdbc.EmbeddedDatabaseConfiguration;
|
||||
import org.springframework.bootstrap.autoconfigure.orm.jpa.test.City;
|
||||
import org.springframework.bootstrap.context.annotation.ComponentScanDetectorConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
@ -39,8 +40,8 @@ public class HibernateJpaAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testEntityManagerCreated() throws Exception {
|
||||
this.context.register(EmbeddedDatabaseConfiguration.class,
|
||||
HibernateJpaAutoConfiguration.class,
|
||||
this.context.register(ComponentScanDetectorConfiguration.class,
|
||||
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertNotNull(this.context.getBean(DataSource.class));
|
||||
@ -49,8 +50,8 @@ public class HibernateJpaAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testDataSourceTransactionManagerNotCreated() throws Exception {
|
||||
this.context.register(EmbeddedDatabaseConfiguration.class,
|
||||
HibernateJpaAutoConfiguration.class,
|
||||
this.context.register(ComponentScanDetectorConfiguration.class,
|
||||
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
|
||||
DataSourceTransactionManagerAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.bootstrap.autoconfigure.web;
|
||||
|
||||
import javax.servlet.Servlet;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnExpression;
|
||||
import org.springframework.bootstrap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
||||
import org.springframework.bootstrap.context.embedded.ConfigurableEmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerCustomizer;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.context.embedded.MockEmbeddedServletContainerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link EmbeddedServletContainerAutoConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class EmbeddedServletContainerAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigEmbeddedWebApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void createFromConfigClass() throws Exception {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
EmbeddedContainerConfiguration.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class);
|
||||
verifyContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containerHasNoServletContext() throws Exception {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
EmbeddedContainerConfiguration.class,
|
||||
EnsureContainerHasNoServletContext.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class);
|
||||
verifyContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizeContainerThroughCallback() throws Exception {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
EmbeddedContainerConfiguration.class,
|
||||
CallbackEmbeddedContainerCustomizer.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class);
|
||||
verifyContext();
|
||||
assertEquals(9000, getContainerFactory().getPort());
|
||||
}
|
||||
|
||||
private void verifyContext() {
|
||||
MockEmbeddedServletContainerFactory containerFactory = getContainerFactory();
|
||||
Servlet servlet = this.context.getBean(Servlet.class);
|
||||
verify(containerFactory.getServletContext()).addServlet("dispatcherServlet",
|
||||
servlet);
|
||||
}
|
||||
|
||||
private MockEmbeddedServletContainerFactory getContainerFactory() {
|
||||
return this.context.getBean(MockEmbeddedServletContainerFactory.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnExpression("true")
|
||||
public static class EmbeddedContainerConfiguration {
|
||||
|
||||
@Bean
|
||||
public EmbeddedServletContainerFactory containerFactory() {
|
||||
return new MockEmbeddedServletContainerFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component
|
||||
public static class EnsureContainerHasNoServletContext implements BeanPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (bean instanceof ConfigurableEmbeddedServletContainerFactory) {
|
||||
MockEmbeddedServletContainerFactory containerFactory = (MockEmbeddedServletContainerFactory) bean;
|
||||
assertNull(containerFactory.getServletContext());
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component
|
||||
public static class CallbackEmbeddedContainerCustomizer implements
|
||||
EmbeddedServletContainerCustomizer {
|
||||
@Override
|
||||
public void customize(ConfigurableEmbeddedServletContainerFactory factory) {
|
||||
factory.setPort(9000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -26,6 +26,7 @@ import org.springframework.bootstrap.TestUtils;
|
||||
import org.springframework.bootstrap.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.bootstrap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
||||
import org.springframework.bootstrap.context.embedded.ConfigurableEmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.properties.ServerProperties;
|
||||
@ -36,6 +37,8 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* Tests for {@link ServerPropertiesAutoConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ServerPropertiesConfigurationTests {
|
||||
@ -60,9 +63,7 @@ public class ServerPropertiesConfigurationTests {
|
||||
@Test
|
||||
public void createFromConfigClass() throws Exception {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
||||
this.context.register(EmbeddedContainerConfiguration.class,
|
||||
EmbeddedContainerCustomizerConfiguration.class,
|
||||
ServerPropertiesConfiguration.class,
|
||||
this.context.register(Config.class, ServerPropertiesAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
TestUtils.addEnviroment(this.context, "server.port:9000");
|
||||
this.context.refresh();
|
||||
@ -76,9 +77,7 @@ public class ServerPropertiesConfigurationTests {
|
||||
public void tomcatProperties() throws Exception {
|
||||
containerFactory = Mockito.mock(TomcatEmbeddedServletContainerFactory.class);
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
||||
this.context.register(EmbeddedContainerCustomizerConfiguration.class,
|
||||
EmbeddedContainerConfiguration.class,
|
||||
ServerPropertiesConfiguration.class,
|
||||
this.context.register(Config.class, ServerPropertiesAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
TestUtils.addEnviroment(this.context, "server.tomcat.basedir:target/foo");
|
||||
this.context.refresh();
|
||||
@ -89,13 +88,18 @@ public class ServerPropertiesConfigurationTests {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class EmbeddedContainerConfiguration {
|
||||
protected static class Config {
|
||||
|
||||
@Bean
|
||||
public EmbeddedServletContainerFactory containerFactory() {
|
||||
return ServerPropertiesConfigurationTests.containerFactory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EmbeddedServletContainerCustomizerBeanPostProcessor embeddedServletContainerCustomizerBeanPostProcessor() {
|
||||
return new EmbeddedServletContainerCustomizerBeanPostProcessor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,109 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.bootstrap.autoconfigure.web;
|
||||
|
||||
import javax.servlet.Servlet;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.bootstrap.context.annotation.ConditionalOnExpression;
|
||||
import org.springframework.bootstrap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
||||
import org.springframework.bootstrap.context.embedded.ConfigurableEmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerCustomizer;
|
||||
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerFactory;
|
||||
import org.springframework.bootstrap.context.embedded.MockEmbeddedServletContainerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import org.junit.Ignore;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* Tests for {@link WebMvcAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Ignore
|
||||
public class WebMvcAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigEmbeddedWebApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void createFromConfigClass() throws Exception {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
WebMvcAutoConfiguration.class, EmbeddedContainerConfiguration.class);
|
||||
verifyContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containerHasNoServletContext() throws Exception {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
WebMvcAutoConfiguration.class, EmbeddedContainerConfiguration.class,
|
||||
EnsureContainerHasNoServletContext.class);
|
||||
verifyContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizeContainerThroughCallback() throws Exception {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
WebMvcAutoConfiguration.class, EmbeddedContainerConfiguration.class,
|
||||
EmbeddedContainerCustomizerConfiguration.class,
|
||||
CallbackEmbeddedContainerCustomizer.class);
|
||||
verifyContext();
|
||||
assertEquals(9000, getContainerFactory().getPort());
|
||||
}
|
||||
|
||||
private void verifyContext() {
|
||||
MockEmbeddedServletContainerFactory containerFactory = getContainerFactory();
|
||||
Servlet servlet = this.context.getBean(Servlet.class);
|
||||
verify(containerFactory.getServletContext()).addServlet("dispatcherServlet",
|
||||
servlet);
|
||||
}
|
||||
|
||||
private MockEmbeddedServletContainerFactory getContainerFactory() {
|
||||
return this.context.getBean(MockEmbeddedServletContainerFactory.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnExpression("true")
|
||||
public static class EmbeddedContainerConfiguration {
|
||||
|
||||
@Bean
|
||||
public EmbeddedServletContainerFactory containerFactory() {
|
||||
return new MockEmbeddedServletContainerFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component
|
||||
public static class EnsureContainerHasNoServletContext implements BeanPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (bean instanceof ConfigurableEmbeddedServletContainerFactory) {
|
||||
MockEmbeddedServletContainerFactory containerFactory = (MockEmbeddedServletContainerFactory) bean;
|
||||
assertNull(containerFactory.getServletContext());
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component
|
||||
public static class CallbackEmbeddedContainerCustomizer implements
|
||||
EmbeddedServletContainerCustomizer {
|
||||
@Override
|
||||
public void customize(ConfigurableEmbeddedServletContainerFactory factory) {
|
||||
factory.setPort(9000);
|
||||
}
|
||||
}
|
||||
// FIXME
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,6 @@ public class JacksonParserTests extends SimpleJsonParserTests {
|
||||
|
||||
@Override
|
||||
protected JsonParser getParser() {
|
||||
return new JacksonParser();
|
||||
return new JacksonJsonParser();
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,6 @@ public class YamlParserTests extends SimpleJsonParserTests {
|
||||
|
||||
@Override
|
||||
protected JsonParser getParser() {
|
||||
return new YamlParser();
|
||||
return new YamlJsonParser();
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public class EnableConfigurationPropertiesTests {
|
||||
// definition created with a direct regsistration (as opposed to a @Bean)
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void testPropertiesBindingWithDefaults() {
|
||||
this.context.register(DefaultConfiguration.class, TestConfiguration.class);
|
||||
this.context.register(TestConfiguration.class, DefaultConfiguration.class);
|
||||
this.context.refresh();
|
||||
String[] beanNames = this.context.getBeanNamesForType(TestProperties.class);
|
||||
assertEquals("Wrong beans: " + Arrays.asList(beanNames), 1, beanNames.length);
|
||||
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.bootstrap.context.annotation;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link OnApplicationContextCondition}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public class OnApplicationContextConditionTest {
|
||||
|
||||
@Test
|
||||
public void forContextById() throws Exception {
|
||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
|
||||
parent.setId("parent");
|
||||
parent.register(ForContextByIdConf.class);
|
||||
|
||||
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
|
||||
child.setId("child");
|
||||
child.setParent(parent);
|
||||
child.register(ForContextByIdConf.class);
|
||||
|
||||
parent.refresh();
|
||||
child.refresh();
|
||||
|
||||
assertThat(parent.containsLocalBean("inParent"), equalTo(true));
|
||||
assertThat(parent.containsLocalBean("inChild"), equalTo(false));
|
||||
|
||||
assertThat(child.containsLocalBean("inParent"), equalTo(false));
|
||||
assertThat(child.containsLocalBean("inChild"), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void createContext() throws Exception {
|
||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
|
||||
ApplicationContextCollector collector = new ApplicationContextCollector();
|
||||
parent.addApplicationListener(collector);
|
||||
parent.register(CreateContext.class);
|
||||
parent.refresh();
|
||||
assertThat(collector.get("child").containsLocalBean("inChild"), equalTo(true));
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// createContextOnBeanMethod
|
||||
// createContextComponent
|
||||
|
||||
private static class ApplicationContextCollector implements
|
||||
ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
private Set<ApplicationContext> contexts = new HashSet<ApplicationContext>();
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
this.contexts.add(event.getApplicationContext());
|
||||
}
|
||||
|
||||
public ApplicationContext get(String id) {
|
||||
for (ApplicationContext context : this.contexts) {
|
||||
if (ObjectUtils.nullSafeEquals(context.getId(), id)) {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("No such ID " + id);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class ForContextByIdConf {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnApplicationContext("parent")
|
||||
public String inParent() {
|
||||
return "inParent";
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnApplicationContext("child")
|
||||
public String inChild() {
|
||||
return "inChild";
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnApplicationContext(value = "child", createIfMissing = true)
|
||||
public static class CreateContext {
|
||||
|
||||
@Bean
|
||||
public String inChild() {
|
||||
return "inChild";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -86,7 +86,8 @@ public class AnnotationConfigEmbeddedWebApplicationContextTests {
|
||||
AnnotationConfigEmbeddedWebApplicationContext parent = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
EmbeddedContainerConfiguration.class);
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
||||
this.context.register(ServletContextAwareConfiguration.class);
|
||||
this.context.register(EmbeddedContainerConfiguration.class,
|
||||
ServletContextAwareConfiguration.class);
|
||||
this.context.setParent(parent);
|
||||
this.context.refresh();
|
||||
verifyContext();
|
||||
|
@ -33,6 +33,8 @@ import org.springframework.core.io.support.PropertiesLoaderUtils;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests for {@link EnableConfigurationProperties}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class EnableConfigurationPropertiesTests {
|
||||
@ -105,6 +107,7 @@ public class EnableConfigurationPropertiesTests {
|
||||
|
||||
@ConfigurationProperties(name = "external")
|
||||
public static class External {
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
@ -118,6 +121,7 @@ public class EnableConfigurationPropertiesTests {
|
||||
|
||||
@ConfigurationProperties(name = "another")
|
||||
public static class Another {
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
|
Loading…
Reference in New Issue
Block a user