Renamed some projects and polish POMs

Issue: #54095231
This commit is contained in:
Phillip Webb
2013-07-26 12:30:54 -07:00
parent 06ddd92438
commit 3f2bb03fb8
309 changed files with 206 additions and 146 deletions

View File

@@ -0,0 +1,174 @@
/*
* 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.boot.config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.util.Assert;
/**
* Sort {@link EnableAutoConfiguration auto-configuration} classes into priority order by
* reading {@link Ordered} and {@link AutoConfigureAfter} annotations (without loading
* classes).
*
* @author Phillip Webb
*/
class AutoConfigurationSorter {
private CachingMetadataReaderFactory metadataReaderFactory;
public AutoConfigurationSorter(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
}
public List<String> getInPriorityOrder(Collection<String> classNames)
throws IOException {
List<AutoConfigurationClass> autoConfigurationClasses = new ArrayList<AutoConfigurationClass>();
for (String className : classNames) {
autoConfigurationClasses.add(new AutoConfigurationClass(className));
}
// Sort initially by order
Collections.sort(autoConfigurationClasses, OrderComparator.INSTANCE);
// Then respect @AutoConfigureAfter
autoConfigurationClasses = sortByAfterAnnotation(autoConfigurationClasses);
List<String> orderedClassNames = new ArrayList<String>();
for (AutoConfigurationClass autoConfigurationClass : autoConfigurationClasses) {
orderedClassNames.add(autoConfigurationClass.toString());
}
return orderedClassNames;
}
private List<AutoConfigurationClass> sortByAfterAnnotation(
Collection<AutoConfigurationClass> autoConfigurationClasses)
throws IOException {
List<AutoConfigurationClass> tosort = new ArrayList<AutoConfigurationClass>(
autoConfigurationClasses);
Set<AutoConfigurationClass> sorted = new LinkedHashSet<AutoConfigurationClass>();
Set<AutoConfigurationClass> processing = new LinkedHashSet<AutoConfigurationClass>();
while (!tosort.isEmpty()) {
doSortByAfterAnnotation(tosort, sorted, processing, null);
}
return new ArrayList<AutoConfigurationClass>(sorted);
}
private void doSortByAfterAnnotation(List<AutoConfigurationClass> tosort,
Set<AutoConfigurationClass> sorted, Set<AutoConfigurationClass> processing,
AutoConfigurationClass current) throws IOException {
if (current == null) {
current = tosort.remove(0);
}
processing.add(current);
for (AutoConfigurationClass after : current.getAfter()) {
Assert.state(!processing.contains(after),
"Cycle @AutoConfigureAfter detected between " + current + " and "
+ after);
if (!sorted.contains(after) && tosort.contains(after)) {
doSortByAfterAnnotation(tosort, sorted, processing, after);
}
}
processing.remove(current);
sorted.add(current);
}
private class AutoConfigurationClass implements Ordered {
private final String className;
private final int order;
private List<AutoConfigurationClass> after;
private Map<String, Object> afterAnnotation;
public AutoConfigurationClass(String className) throws IOException {
this.className = className;
MetadataReader metadataReader = AutoConfigurationSorter.this.metadataReaderFactory
.getMetadataReader(className);
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
// Read @Order annotation
Map<String, Object> orderedAnnotation = metadata
.getAnnotationAttributes(Order.class.getName());
this.order = (orderedAnnotation == null ? Ordered.LOWEST_PRECEDENCE
: (Integer) orderedAnnotation.get("value"));
// Read @AutoConfigureAfter annotation
this.afterAnnotation = metadata.getAnnotationAttributes(
AutoConfigureAfter.class.getName(), true);
}
@Override
public int getOrder() {
return this.order;
}
public List<AutoConfigurationClass> getAfter() throws IOException {
if (this.after == null) {
if (this.afterAnnotation == null) {
this.after = Collections.emptyList();
}
else {
this.after = new ArrayList<AutoConfigurationClass>();
for (String afterClass : (String[]) this.afterAnnotation.get("value")) {
this.after.add(new AutoConfigurationClass(afterClass));
}
}
}
return this.after;
}
@Override
public String toString() {
return this.className;
}
@Override
public int hashCode() {
return this.className.hashCode();
}
@Override
public boolean equals(Object obj) {
return this.className.equals(((AutoConfigurationClass) obj).className);
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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.boot.config;
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 Phillip Webb
* @author Dave Syer
*/
public abstract class AutoConfigurationUtils {
private static final 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 ex) {
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);
}
}
}
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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.boot.config;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Hint for that an {@link EnableAutoConfiguration auto-configuration} should be applied
* after the specified auto-configuration classes.
*
* @author Phillip Webb
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface AutoConfigureAfter {
Class<?>[] value();
}

View File

@@ -0,0 +1,155 @@
/*
* 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.boot.config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Helper to detect a component scan declared in the enclosing context (normally on a
* {@code @Configuration} class). Once the component scan is detected, the base packages
* are stored for retrieval later.
*
* @author Dave Syer
* @author Phillip Webb
* @see AutoConfigurationUtils
*/
class ComponentScanDetector implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
private final Log logger = LogFactory.getLog(getClass());
private BeanFactory beanFactory;
private MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
final BeanDefinitionRegistry registry) {
storeComponentScanBasePackages();
}
private void storeComponentScanBasePackages() {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
storeComponentScanBasePackages((ConfigurableListableBeanFactory) this.beanFactory);
}
else {
if (this.logger.isWarnEnabled()) {
this.logger
.warn("Unable to read @ComponentScan annotations for auto-configure");
}
}
}
private void storeComponentScanBasePackages(
ConfigurableListableBeanFactory beanFactory) {
List<String> basePackages = new ArrayList<String>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
String[] basePackagesAttribute = (String[]) beanDefinition
.getAttribute("componentScanBasePackages");
if (basePackagesAttribute != null) {
basePackages.addAll(Arrays.asList(basePackagesAttribute));
}
AnnotationMetadata metadata = getMetadata(beanDefinition);
basePackages.addAll(getBasePackages(metadata));
}
AutoConfigurationUtils.storeBasePackages(beanFactory, basePackages);
}
private AnnotationMetadata getMetadata(BeanDefinition beanDefinition) {
if (beanDefinition instanceof AbstractBeanDefinition
&& ((AbstractBeanDefinition) beanDefinition).hasBeanClass()) {
Class<?> beanClass = ((AbstractBeanDefinition) beanDefinition).getBeanClass();
if (Enhancer.isEnhanced(beanClass)) {
beanClass = beanClass.getSuperclass();
}
return new StandardAnnotationMetadata(beanClass, true);
}
String className = beanDefinition.getBeanClassName();
if (className != null) {
try {
MetadataReader metadataReader = this.metadataReaderFactory
.getMetadataReader(className);
return metadataReader.getAnnotationMetadata();
}
catch (IOException ex) {
if (this.logger.isDebugEnabled()) {
this.logger.debug(
"Could not find class file for introspecting @ComponentScan classes: "
+ className, ex);
}
}
}
return null;
}
private List<String> getBasePackages(AnnotationMetadata metadata) {
AnnotationAttributes attributes = AnnotationAttributes
.fromMap((metadata == null ? null : metadata.getAnnotationAttributes(
ComponentScan.class.getName(), true)));
if (attributes != null) {
List<String> basePackages = new ArrayList<String>();
addAllHavingText(basePackages, attributes.getStringArray("value"));
addAllHavingText(basePackages, attributes.getStringArray("basePackages"));
for (String packageClass : attributes.getStringArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(packageClass));
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(metadata.getClassName()));
}
return basePackages;
}
return Collections.emptyList();
}
private void addAllHavingText(List<String> list, String[] strings) {
for (String s : strings) {
if (StringUtils.hasText(s)) {
list.add(s);
}
}
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.boot.config;
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.springframework.boot.strap.context.condition.ConditionalOnBean;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.boot.strap.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.strap.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.SpringFactoriesLoader;
/**
* Enable auto-configuration of the Spring Application Context, attempting to guess and
* configure beans that you are likely to need.
*
* Auto-configuration classes are usually applied based on your classpath and what beans
* you have defined. For example, If you have {@code tomat-embedded.jar} on your classpath
* you are likely to want a {@link TomcatEmbeddedServletContainerFactory} (unless you have
* defined your own {@link EmbeddedServletContainerFactory} bean).
*
* <p>
* Auto-configuration tries to be as intelligent as possible and will back-away as you
* define more of your own configuration. You can always manually {@link #exclude()} any
* configuration that you never want to apply. Auto-configuration is always applied after
* user-defined beans have been registered.
*
* <p>
* Auto-configuration classes are regular Spring {@link Configuration} beans. They are
* located using the {@link SpringFactoriesLoader} mechanism (keyed against this class).
* Generally auto-configuration beans are {@link Conditional @Conditional} beans (most
* often using {@link ConditionalOnClass @ConditionalOnClass} and
* {@link ConditionalOnMissingBean @ConditionalOnMissingBean} annotations).
*
* @author Phillip Webb
* @see ConditionalOnBean
* @see ConditionalOnMissingBean
* @see ConditionalOnClass
* @see AutoConfigureAfter
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
/**
* Exclude specific auto-configuration classes such that they will never be applied.
*/
Class<?>[] exclude() default {};
}

View File

@@ -0,0 +1,88 @@
/*
* 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.boot.config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.DeferredImportSelector;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.AnnotationMetadata;
/**
* {@link DeferredImportSelector} to handle {@link EnableAutoConfiguration
* auto-configuration}.
*
* @author Phillip Webb
* @see EnableAutoConfiguration
*/
@Order(Ordered.LOWEST_PRECEDENCE)
class EnableAutoConfigurationImportSelector implements DeferredImportSelector,
BeanClassLoaderAware, ResourceLoaderAware {
private ClassLoader beanClassLoader;
private ResourceLoader resourceLoader;
@Override
public String[] selectImports(AnnotationMetadata metadata) {
try {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata
.getAnnotationAttributes(EnableAutoConfiguration.class.getName(),
true));
// Find all possible auto configuration classes
List<String> factories = new ArrayList<String>(
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,
this.beanClassLoader));
// Remove those specifically disabled
factories.removeAll(Arrays.asList(attributes.getStringArray("exclude")));
// Sort
factories = new AutoConfigurationSorter(this.resourceLoader)
.getInPriorityOrder(factories);
// Always add the ComponentScanDetector as the first in the list
factories.add(0, ComponentScanDetector.class.getName());
return factories.toArray(new String[factories.size()]);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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.boot.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
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}.
*
* @author Dave Syer
*/
@Configuration
@ConditionalOnMissingBean(MessageSource.class)
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MessageSourceAutoConfiguration {
@Value("${spring.messages.basename:messages}")
private String basename;
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename(this.basename);
return messageSource;
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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.boot.config;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
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
* {@link PropertySourcesPlaceholderConfigurer}.
*
* @author Phillip Webb
* @author Dave Syer
*/
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class PropertyPlaceholderAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(
ApplicationContext context) {
return new PropertySourcesPlaceholderConfigurer();
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.boot.config.batch;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.CommandLineRunner;
import org.springframework.boot.strap.ExitCodeGenerator;
import org.springframework.boot.strap.context.condition.ConditionalOnBean;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Batch.
*
* @author Dave Syer
*/
@Configuration
@ConditionalOnClass({ JobLauncher.class })
public class BatchAutoConfiguration {
@Bean
// Harmless to always include this, but maybe could make it conditional as well
public BatchDatabaseInitializer batchDatabaseInitializer() {
return new BatchDatabaseInitializer();
}
@Bean
@ConditionalOnMissingBean(CommandLineRunner.class)
@ConditionalOnBean(JobLauncher.class)
public JobLauncherCommandLineRunner jobLauncherCommandLineRunner() {
return new JobLauncherCommandLineRunner();
}
@Bean
@ConditionalOnMissingBean(ExitCodeGenerator.class)
@ConditionalOnBean(JobLauncher.class)
public ExitCodeGenerator jobExecutionExitCodeGenerator() {
return new JobExecutionExitCodeGenerator();
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.boot.config.batch;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.springframework.batch.support.DatabaseType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.stereotype.Component;
/**
* Initialize the Spring Batch schema (ignoring errors, so should be idempotent).
*
* @author Dave Syer
*/
@Component
public class BatchDatabaseInitializer {
@Autowired
private DataSource dataSource;
@Autowired
private ResourceLoader resourceLoader;
@Value("${spring.batch.schema:classpath:org/springframework/batch/core/schema-@@platform@@.sql}")
private String schemaLocation = "classpath:org/springframework/batch/core/schema-@@platform@@.sql";
@PostConstruct
protected void initialize() throws Exception {
String platform = DatabaseType.fromMetaData(this.dataSource).toString()
.toLowerCase();
if ("hsql".equals(platform)) {
platform = "hsqldb";
}
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(this.resourceLoader.getResource(this.schemaLocation.replace(
"@@platform@@", platform)));
populator.setContinueOnError(true);
DatabasePopulatorUtils.execute(populator, this.dataSource);
}
}

View File

@@ -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.boot.config.batch;
import org.springframework.batch.core.JobExecution;
import org.springframework.context.ApplicationEvent;
/**
* Spring {@link ApplicationEvent} encapsulating a {@link JobExecution}.
*
* @author Dave Syer
*/
public class JobExecutionEvent extends ApplicationEvent {
private JobExecution execution;
/**
* @param execution the job execution
*/
public JobExecutionEvent(JobExecution execution) {
super(execution);
this.execution = execution;
}
/**
* @return the job execution
*/
public JobExecution getJobExecution() {
return this.execution;
}
}

View File

@@ -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.boot.config.batch;
import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.core.JobExecution;
import org.springframework.boot.strap.ExitCodeGenerator;
import org.springframework.context.ApplicationListener;
/**
* {@link ExitCodeGenerator} for {@link JobExecutionEvent}s.
*
* @author Dave Syer
*/
public class JobExecutionExitCodeGenerator implements
ApplicationListener<JobExecutionEvent>, ExitCodeGenerator {
private List<JobExecution> executions = new ArrayList<JobExecution>();
@Override
public void onApplicationEvent(JobExecutionEvent event) {
this.executions.add(event.getJobExecution());
}
@Override
public int getExitCode() {
for (JobExecution execution : this.executions) {
if (execution.getStatus().ordinal() > 0) {
return execution.getStatus().ordinal();
}
}
return 0;
}
}

View File

@@ -0,0 +1,82 @@
/*
* 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.boot.config.batch;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionException;
import org.springframework.batch.core.converter.DefaultJobParametersConverter;
import org.springframework.batch.core.converter.JobParametersConverter;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.strap.CommandLineRunner;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
/**
* {@link CommandLineRunner} to {@link JobLauncher launch} Spring Batch jobs.
*
* @author Dave Syer
*/
@Component
public class JobLauncherCommandLineRunner implements CommandLineRunner,
ApplicationEventPublisherAware {
private static Log logger = LogFactory.getLog(JobLauncherCommandLineRunner.class);
@Autowired(required = false)
private JobParametersConverter converter = new DefaultJobParametersConverter();
@Autowired
private JobLauncher jobLauncher;
@Autowired(required = false)
private Collection<Job> jobs = Collections.emptySet();
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
@Override
public void run(String... args) throws JobExecutionException {
logger.info("Running default command line with: " + Arrays.asList(args));
launchJobFromProperties(StringUtils.splitArrayElementsIntoProperties(args, "="));
}
protected void launchJobFromProperties(Properties properties)
throws JobExecutionException {
for (Job job : this.jobs) {
JobExecution execution = this.jobLauncher.run(job,
this.converter.getJobParameters(properties));
if (this.publisher != null) {
this.publisher.publishEvent(new JobExecutionEvent(execution));
}
}
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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.boot.config.data;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's JPA Repositories.
*
* @author Phillip Webb
* @see EnableJpaRepositories
*/
@Configuration
@ConditionalOnClass(JpaRepository.class)
@ConditionalOnMissingBean(JpaRepositoryFactoryBean.class)
@Import(JpaRepositoriesAutoConfigureRegistrar.class)
public class JpaRepositoriesAutoConfiguration {
}

View File

@@ -0,0 +1,122 @@
/*
* 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.boot.config.data;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
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.boot.config.AutoConfigurationUtils;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension;
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
import org.springframework.data.repository.config.RepositoryBeanDefinitionBuilder;
import org.springframework.data.repository.config.RepositoryBeanNameGenerator;
import org.springframework.data.repository.config.RepositoryConfiguration;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
import org.springframework.util.Assert;
/**
* {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data JPA
* Repositories.
*
* @author Phillip Webb
*/
class JpaRepositoriesAutoConfigureRegistrar implements ImportBeanDefinitionRegistrar,
BeanFactoryAware, BeanClassLoaderAware {
private BeanFactory beanFactory;
private ClassLoader beanClassLoader;
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
final BeanDefinitionRegistry registry) {
final ResourceLoader resourceLoader = new DefaultResourceLoader();
final AnnotationRepositoryConfigurationSource configurationSource = getConfigurationSource();
final RepositoryConfigurationExtension extension = new JpaRepositoryConfigExtension();
extension.registerBeansForRoot(registry, configurationSource);
final RepositoryBeanNameGenerator generator = new RepositoryBeanNameGenerator();
generator.setBeanClassLoader(this.beanClassLoader);
Collection<RepositoryConfiguration<AnnotationRepositoryConfigurationSource>> repositoryConfigurations = extension
.getRepositoryConfigurations(configurationSource, resourceLoader);
for (final RepositoryConfiguration<AnnotationRepositoryConfigurationSource> repositoryConfiguration : repositoryConfigurations) {
RepositoryBeanDefinitionBuilder builder = new RepositoryBeanDefinitionBuilder(
repositoryConfiguration, extension);
BeanDefinitionBuilder definitionBuilder = builder.build(registry,
resourceLoader);
extension.postProcess(definitionBuilder, configurationSource);
String beanName = generator.generateBeanName(
definitionBuilder.getBeanDefinition(), registry);
registry.registerBeanDefinition(beanName,
definitionBuilder.getBeanDefinition());
}
}
private AnnotationRepositoryConfigurationSource getConfigurationSource() {
StandardAnnotationMetadata metadata = new StandardAnnotationMetadata(
EnableJpaRepositoriesConfiguration.class, true);
AnnotationRepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource(
metadata, EnableJpaRepositories.class) {
@Override
public java.lang.Iterable<String> getBasePackages() {
return JpaRepositoriesAutoConfigureRegistrar.this.getBasePackages();
};
};
return configurationSource;
}
protected Iterable<String> getBasePackages() {
List<String> basePackages = AutoConfigurationUtils
.getBasePackages(this.beanFactory);
Assert.notEmpty(
basePackages,
"Unable to find JPA repository base packages, please define "
+ "a @ComponentScan annotation or disable JpaRepositoriesAutoConfigure");
return basePackages;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@EnableJpaRepositories
private static class EnableJpaRepositoriesConfiguration {
}
}

View File

@@ -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.boot.config.jdbc;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.util.StringUtils;
/**
* Base class for configuration of a database pool.
*
* @author Dave Syer
*/
public class AbstractDataSourceConfiguration {
// TODO: add pool parameters
@Value("${spring.database.driverClassName:}")
private String driverClassName;
@Value("${spring.database.url:}")
private String url;
@Value("${spring.database.username:sa}")
private String username;
@Value("${spring.database.password:}")
private String password;
protected String getDriverClassName() {
if (StringUtils.hasText(this.driverClassName)) {
return this.driverClassName;
}
EmbeddedDatabaseType embeddedDatabaseType = EmbeddedDatabaseConfiguration
.getEmbeddedDatabaseType();
this.driverClassName = EmbeddedDatabaseConfiguration
.getEmbeddedDatabaseDriverClass(embeddedDatabaseType);
if (!StringUtils.hasText(this.driverClassName)) {
throw new BeanCreationException(
"Cannot determine embedded database driver class for database type "
+ embeddedDatabaseType
+ ". If you want an embedded database please put a supoprted one on the classpath.");
}
return this.driverClassName;
}
protected String getUrl() {
if (StringUtils.hasText(this.url)) {
return this.url;
}
EmbeddedDatabaseType embeddedDatabaseType = EmbeddedDatabaseConfiguration
.getEmbeddedDatabaseType();
this.url = EmbeddedDatabaseConfiguration
.getEmbeddedDatabaseUrl(embeddedDatabaseType);
if (!StringUtils.hasText(this.url)) {
throw new BeanCreationException(
"Cannot determine embedded database url for database type "
+ embeddedDatabaseType
+ ". If you want an embedded database please put a supported on on the classpath.");
}
return this.url;
}
protected String getUsername() {
return this.username;
}
protected String getPassword() {
return this.password;
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.boot.config.jdbc;
import java.sql.SQLException;
import javax.annotation.PreDestroy;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.DataAccessResourceFailureException;
/**
* Configuration for a Commons DBCP database pool. The DBCP pool is popular but not
* recommended in high volume environments (the Tomcat DataSource is more reliable).
*
* @author Dave Syer
*/
@Configuration
public class BasicDataSourceConfiguration extends AbstractDataSourceConfiguration {
private static Log logger = LogFactory.getLog(BasicDataSourceConfiguration.class);
private BasicDataSource pool;
@Bean
public DataSource dataSource() {
logger.info("Hint: using Commons DBCP BasicDataSource. It's going to work, "
+ "but the Tomcat DataSource is more reliable.");
this.pool = new BasicDataSource();
this.pool.setDriverClassName(getDriverClassName());
this.pool.setUrl(getUrl());
this.pool.setUsername(getUsername());
this.pool.setPassword(getPassword());
return this.pool;
}
@PreDestroy
public void close() {
if (this.pool != null) {
try {
this.pool.close();
}
catch (SQLException ex) {
throw new DataAccessResourceFailureException(
"Could not close data source", ex);
}
}
}
}

View File

@@ -0,0 +1,300 @@
/*
* 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.boot.config.jdbc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.context.condition.ConditionLogUtils;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link DataSource}.
*
* @author Dave Syer
*/
@Configuration
@ConditionalOnClass(EmbeddedDatabaseType.class /* Spring JDBC */)
@ConditionalOnMissingBean(DataSource.class)
public class DataSourceAutoConfiguration {
private static Log logger = LogFactory.getLog(DataSourceAutoConfiguration.class);
@Autowired(required = false)
private DataSource dataSource;
@Autowired
private ApplicationContext applicationContext;
@Conditional(DataSourceAutoConfiguration.EmbeddedDatabaseCondition.class)
@Import(EmbeddedDatabaseConfiguration.class)
protected static class EmbeddedConfiguration {
}
@Conditional(DataSourceAutoConfiguration.TomcatDatabaseCondition.class)
@Import(TomcatDataSourceConfiguration.class)
protected static class TomcatConfiguration {
}
@Conditional(DataSourceAutoConfiguration.BasicDatabaseCondition.class)
@Import(BasicDataSourceConfiguration.class)
protected static class DbcpConfiguration {
}
@Configuration
@Conditional(DataSourceAutoConfiguration.SomeDatabaseCondition.class)
// FIXME: make this @ConditionalOnBean(DataSource.class)
protected static class JdbcTemplateConfiguration {
@Autowired(required = false)
private DataSource dataSource;
@Bean
@ConditionalOnMissingBean(JdbcOperations.class)
public JdbcOperations jdbcTemplate() {
return new JdbcTemplate(this.dataSource);
}
@Bean
@ConditionalOnMissingBean(NamedParameterJdbcOperations.class)
public NamedParameterJdbcOperations namedParameterJdbcTemplate() {
return new NamedParameterJdbcTemplate(this.dataSource);
}
}
@Value("${spring.database.schema:classpath*:schema-${spring.database.platform:all}.sql}")
private String schemaLocations = "";
@PostConstruct
protected void initialize() throws Exception {
if (this.dataSource == null) {
logger.debug("No DataSource found so not initializing");
return;
}
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
boolean exists = false;
List<Resource> resources = new ArrayList<Resource>();
for (String location : StringUtils
.commaDelimitedListToStringArray(this.schemaLocations)) {
resources
.addAll(Arrays.asList(this.applicationContext.getResources(location)));
}
for (Resource resource : resources) {
if (resource.exists()) {
exists = true;
populator.addScript(resource);
populator.setContinueOnError(true);
}
}
if (exists) {
DatabasePopulatorUtils.execute(populator, this.dataSource);
}
}
static class SomeDatabaseCondition implements Condition {
private Log logger = LogFactory.getLog(getClass());
private Condition tomcatCondition = new TomcatDatabaseCondition();
private Condition dbcpCondition = new BasicDatabaseCondition();
private Condition embeddedCondition = new EmbeddedDatabaseCondition();
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String checking = ConditionLogUtils.getPrefix(this.logger, metadata);
if (this.tomcatCondition.matches(context, metadata)
|| this.dbcpCondition.matches(context, metadata)
|| this.embeddedCondition.matches(context, metadata)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug(checking + "Existing auto database "
+ "detected: match result true");
}
return true;
}
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
context.getBeanFactory(), DataSource.class, true, false).length > 0) {
if (this.logger.isDebugEnabled()) {
this.logger.debug(checking + "Existing bean configured database "
+ "detected: match result true");
}
return true;
}
if (this.logger.isDebugEnabled()) {
this.logger.debug(checking + "Existing bean configured database not "
+ "detected: match result false");
}
return false;
}
}
static class TomcatDatabaseCondition extends NonEmbeddedDatabaseCondition {
@Override
protected String getDataSourecClassName() {
return "org.apache.tomcat.jdbc.pool.DataSource";
}
}
static class BasicDatabaseCondition extends NonEmbeddedDatabaseCondition {
private Condition condition = new TomcatDatabaseCondition();
@Override
protected String getDataSourecClassName() {
return "org.apache.commons.dbcp.BasicDataSource";
}
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (this.condition.matches(context, metadata)) {
return false; // prefer Tomcat pool
}
return super.matches(context, metadata);
}
}
static abstract class NonEmbeddedDatabaseCondition implements Condition {
private Log logger = LogFactory.getLog(getClass());
protected abstract String getDataSourecClassName();
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String checking = ConditionLogUtils.getPrefix(this.logger, metadata);
if (!ClassUtils.isPresent(getDataSourecClassName(), null)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug(checking + "Tomcat DataSource pool not found");
}
return false;
}
String driverClassName = getDriverClassName(context, checking);
String url = getUrl(context);
if (driverClassName != null && url != null
&& ClassUtils.isPresent(driverClassName, null)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug(checking + "Driver class " + driverClassName
+ " found");
}
return true;
}
if (this.logger.isDebugEnabled()) {
this.logger.debug(checking + "Driver class " + driverClassName
+ " not found");
}
return false;
}
private String getDriverClassName(ConditionContext context, String checking) {
String driverClassName = context.getEnvironment().getProperty(
"spring.database.driverClassName");
if (this.logger.isDebugEnabled()) {
this.logger.debug(checking
+ "Spring JDBC detected (embedded database type is "
+ EmbeddedDatabaseConfiguration.getEmbeddedDatabaseType() + ").");
}
if (driverClassName == null) {
driverClassName = EmbeddedDatabaseConfiguration
.getEmbeddedDatabaseDriverClass(EmbeddedDatabaseConfiguration
.getEmbeddedDatabaseType());
}
return driverClassName;
}
private String getUrl(ConditionContext context) {
String url = context.getEnvironment().getProperty("spring.database.url");
if (url == null) {
url = EmbeddedDatabaseConfiguration
.getEmbeddedDatabaseUrl(EmbeddedDatabaseConfiguration
.getEmbeddedDatabaseType());
}
return url;
}
}
static class EmbeddedDatabaseCondition implements Condition {
private Log logger = LogFactory.getLog(getClass());
private Condition tomcatCondition = new TomcatDatabaseCondition();
private Condition dbcpCondition = new BasicDatabaseCondition();
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String checking = ConditionLogUtils.getPrefix(this.logger, metadata);
if (this.tomcatCondition.matches(context, metadata)
|| this.dbcpCondition.matches(context, metadata)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug(checking + "Existing non-embedded "
+ "database detected: match result false");
}
return false;
}
if (this.logger.isDebugEnabled()) {
this.logger.debug(checking
+ "Spring JDBC detected (embedded database type is "
+ EmbeddedDatabaseConfiguration.getEmbeddedDatabaseType() + ").");
}
return EmbeddedDatabaseConfiguration.getEmbeddedDatabaseType() != null;
}
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.boot.config.jdbc;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.context.condition.ConditionalOnBean;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
/**
* {@link EnableAutoConfiguration Auto-configuration} for
* {@link DataSourceTransactionManager}.
*
* @author Dave Syer
*/
@Configuration
@ConditionalOnClass({ JdbcTemplate.class, PlatformTransactionManager.class })
public class DataSourceTransactionManagerAutoConfiguration implements Ordered {
@Override
public int getOrder() {
return Integer.MAX_VALUE;
}
@Autowired(required = false)
private DataSource dataSource;
@Bean
@ConditionalOnMissingBean(name = "transactionManager")
@ConditionalOnBean(DataSource.class)
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(this.dataSource);
}
}

View File

@@ -0,0 +1,99 @@
/*
* 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.boot.config.jdbc;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.annotation.PreDestroy;
import javax.sql.DataSource;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.util.ClassUtils;
/**
* {@link EnableAutoConfiguration Auto-configuration} for embedded databases.
*
* @author Phillip Webb
*/
@Configuration
public class EmbeddedDatabaseConfiguration {
private static final Map<EmbeddedDatabaseType, String> EMBEDDED_DATABASE_DRIVER_CLASSES;
private static final Map<EmbeddedDatabaseType, String> EMBEDDED_DATABASE_URLS;
private EmbeddedDatabase database;
static {
EMBEDDED_DATABASE_DRIVER_CLASSES = new LinkedHashMap<EmbeddedDatabaseType, String>();
EMBEDDED_DATABASE_DRIVER_CLASSES.put(EmbeddedDatabaseType.H2, "org.h2.Driver");
EMBEDDED_DATABASE_DRIVER_CLASSES.put(EmbeddedDatabaseType.DERBY,
"org.apache.derby.jdbc.EmbeddedDriver");
EMBEDDED_DATABASE_DRIVER_CLASSES.put(EmbeddedDatabaseType.HSQL,
"org.hsqldb.jdbcDriver");
EMBEDDED_DATABASE_URLS = new LinkedHashMap<EmbeddedDatabaseType, String>();
EMBEDDED_DATABASE_URLS.put(EmbeddedDatabaseType.H2,
"jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1");
EMBEDDED_DATABASE_URLS.put(EmbeddedDatabaseType.DERBY,
"jdbc:derby:memory:testdb;create=true");
EMBEDDED_DATABASE_URLS.put(EmbeddedDatabaseType.HSQL, "jdbc:hsqldb:mem:testdb");
}
@Bean
public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
.setType(getEmbeddedDatabaseType());
this.database = builder.build();
return this.database;
}
@PreDestroy
public void close() {
if (this.database != null) {
this.database.shutdown();
}
}
public static String getEmbeddedDatabaseDriverClass(
EmbeddedDatabaseType embeddedDatabaseType) {
return EMBEDDED_DATABASE_DRIVER_CLASSES.get(embeddedDatabaseType);
}
public static String getEmbeddedDatabaseUrl(EmbeddedDatabaseType embeddedDatabaseType) {
return EMBEDDED_DATABASE_URLS.get(embeddedDatabaseType);
}
public static EmbeddedDatabaseType getEmbeddedDatabaseType() {
for (Map.Entry<EmbeddedDatabaseType, String> entry : EMBEDDED_DATABASE_DRIVER_CLASSES
.entrySet()) {
if (ClassUtils.isPresent(entry.getValue(),
EmbeddedDatabaseConfiguration.class.getClassLoader())) {
return entry.getKey();
}
}
return null;
}
}

View File

@@ -0,0 +1,53 @@
/*
* 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.boot.config.jdbc;
import javax.annotation.PreDestroy;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration for a Tomcat database pool. The Tomcat pool provides superior performance
* and tends not to deadlock in high volume environments.
*
* @author Dave Syer
*/
@Configuration
public class TomcatDataSourceConfiguration extends AbstractDataSourceConfiguration {
private org.apache.tomcat.jdbc.pool.DataSource pool;
@Bean
public DataSource dataSource() {
this.pool = new org.apache.tomcat.jdbc.pool.DataSource();
this.pool.setDriverClassName(getDriverClassName());
this.pool.setUrl(getUrl());
this.pool.setUsername(getUsername());
this.pool.setPassword(getPassword());
return this.pool;
}
@PreDestroy
public void close() {
if (this.pool != null) {
this.pool.close();
}
}
}

View File

@@ -0,0 +1,89 @@
/*
* 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.boot.config.orm.jpa;
import java.util.LinkedHashMap;
import java.util.Map;
import org.hibernate.ejb.HibernateEntityManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringUtils;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Hibernate JPA.
*
* @author Phillip Webb
*/
@Configuration
@ConditionalOnClass(HibernateEntityManager.class)
@EnableTransactionManagement
public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
private static final Map<EmbeddedDatabaseType, String> EMBEDDED_DATABASE_DIALECTS;
static {
EMBEDDED_DATABASE_DIALECTS = new LinkedHashMap<EmbeddedDatabaseType, String>();
EMBEDDED_DATABASE_DIALECTS.put(EmbeddedDatabaseType.HSQL,
"org.hibernate.dialect.HSQLDialect");
}
@Value("${spring.jpa.databasePlatform:${spring.jpa.database_platform:}}")
private String databasePlatform;
@Value("${spring.jpa.database:DEFAULT}")
private Database database = Database.DEFAULT;
@Value("${spring.jpa.showSql:${spring.jpa.show_sql:false}}")
private boolean showSql;
@Value("${spring.jpa.ddlAuto:${spring.jpa.ddl_auto:none}}")
private String ddlAuto; // e.g. none, validate, update, create, create-drop
@Bean
@Override
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setShowSql(this.showSql);
if (StringUtils.hasText(this.databasePlatform)) {
adapter.setDatabasePlatform(this.databasePlatform);
}
adapter.setDatabase(this.database);
return adapter;
}
@Override
protected void configure(
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
Map<String, Object> properties = entityManagerFactoryBean.getJpaPropertyMap();
// FIXME: detect EhCache
properties.put("hibernate.cache.provider_class",
"org.hibernate.cache.HashtableCacheProvider");
if (StringUtils.hasLength(this.ddlAuto) && !"none".equals(this.ddlAuto)) {
properties.put("hibernate.hbm2ddl.auto", this.ddlAuto);
}
}
}

View File

@@ -0,0 +1,144 @@
/*
* 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.boot.config.orm.jpa;
import java.util.List;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
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.boot.config.AutoConfigurationUtils;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.config.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.boot.strap.context.condition.ConditionalOnBean;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.condition.ConditionalOnExpression;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.boot.strap.context.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.Assert;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Base {@link EnableAutoConfiguration Auto-configuration} for JPA.
*
* @author Phillip Webb
* @author Dave Syer
*/
@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class,
EnableTransactionManagement.class, EntityManager.class })
@ConditionalOnBean(DataSource.class)
public abstract class JpaBaseConfiguration implements BeanFactoryAware {
private ConfigurableListableBeanFactory beanFactory;
@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory().getObject());
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
entityManagerFactoryBean.setDataSource(getDataSource());
entityManagerFactoryBean.setPackagesToScan(getPackagesToScan());
configure(entityManagerFactoryBean);
return entityManagerFactoryBean;
}
@Configuration
@ConditionalOnWebApplication
@ConditionalOnMissingBean({ OpenEntityManagerInViewInterceptor.class,
OpenEntityManagerInViewFilter.class })
@ConditionalOnExpression("${spring.jpa.openInView:${spring.jpa.open_in_view:true}}")
protected static class JpaWebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addWebRequestInterceptor(openEntityManagerInViewInterceptor());
}
@Bean
public OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor() {
return new OpenEntityManagerInViewInterceptor();
}
}
/**
* Determines if the {@code dataSource} being used by Spring was created from
* {@link EmbeddedDatabaseConfiguration}.
* @return true if the data source was auto-configured.
*/
protected boolean isAutoConfiguredDataSource() {
try {
BeanDefinition beanDefinition = this.beanFactory
.getBeanDefinition("dataSource");
return EmbeddedDatabaseConfiguration.class.getName().equals(
beanDefinition.getFactoryBeanName());
}
catch (NoSuchBeanDefinitionException ex) {
return false;
}
}
@Bean
public abstract JpaVendorAdapter jpaVendorAdapter();
protected DataSource getDataSource() {
try {
return this.beanFactory.getBean("dataSource", DataSource.class);
}
catch (RuntimeException ex) {
return this.beanFactory.getBean(DataSource.class);
}
}
protected String[] getPackagesToScan() {
List<String> basePackages = AutoConfigurationUtils
.getBasePackages(this.beanFactory);
Assert.notEmpty(basePackages,
"Unable to find JPA packages to scan, please define "
+ "a @ComponentScan annotation or disable JpaAutoConfiguration");
return basePackages.toArray(new String[basePackages.size()]);
}
protected void configure(
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.boot.config.reactor;
import org.springframework.boot.config.AutoConfigureAfter;
import org.springframework.boot.config.web.WebMvcAutoConfiguration;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import reactor.core.Environment;
import reactor.core.Reactor;
import reactor.spring.context.ConsumerBeanPostProcessor;
/**
* @author Dave Syer
*/
@Configuration
@ConditionalOnClass(ConsumerBeanPostProcessor.class)
@ConditionalOnMissingBean(Reactor.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class ReactorAutoConfiguration {
@Bean
public Environment reactorEnvironment() {
return new Environment(); // TODO: use Spring Environment to configure?
}
@Bean
public Reactor rootReactor() {
return reactorEnvironment().getRootReactor();
}
@Bean
@Order(Ordered.LOWEST_PRECEDENCE)
protected ConsumerBeanPostProcessor reactorConsumerBeanPostProcessor() {
return new ConsumerBeanPostProcessor();
}
}

View File

@@ -0,0 +1,171 @@
/*
* 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.boot.config.thymeleaf;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import javax.servlet.Servlet;
import nz.net.ultraq.thymeleaf.LayoutDialect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.config.AutoConfigureAfter;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.config.web.WebMvcAutoConfiguration;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.thymeleaf.TemplateProcessingParameters;
import org.thymeleaf.dialect.IDialect;
import org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect;
import org.thymeleaf.resourceresolver.IResourceResolver;
import org.thymeleaf.spring3.SpringTemplateEngine;
import org.thymeleaf.spring3.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ITemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Thymeleaf templating.
*
* @author Dave Syer
*/
@Configuration
@ConditionalOnClass(SpringTemplateEngine.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class ThymeleafAutoConfiguration {
@Configuration
@ConditionalOnMissingBean(name = "defaultTemplateResolver")
protected static class DefaultTemplateResolverConfiguration {
@Autowired
private ResourceLoader resourceLoader = new DefaultResourceLoader();
@Value("${spring.template.prefix:classpath:/templates/}")
private String prefix = "classpath:/templates/";
@Value("${spring.template.suffix:.html}")
private String suffix = ".html";
@Value("${spring.template.cache:true}")
private boolean cacheable;
@Value("${spring.template.mode:HTML5}")
private String templateMode = "HTML5";
@Bean
public ITemplateResolver defaultTemplateResolver() {
TemplateResolver resolver = new TemplateResolver();
resolver.setResourceResolver(new IResourceResolver() {
@Override
public InputStream getResourceAsStream(
TemplateProcessingParameters templateProcessingParameters,
String resourceName) {
try {
return DefaultTemplateResolverConfiguration.this.resourceLoader
.getResource(resourceName).getInputStream();
}
catch (IOException ex) {
return null;
}
}
@Override
public String getName() {
return "SPRING";
}
});
resolver.setPrefix(this.prefix);
resolver.setSuffix(this.suffix);
resolver.setTemplateMode(this.templateMode);
resolver.setCacheable(this.cacheable);
return resolver;
}
}
@Configuration
@ConditionalOnMissingBean(SpringTemplateEngine.class)
protected static class ThymeleafDefaultConfiguration {
@Autowired
private Collection<ITemplateResolver> templateResolvers = Collections.emptySet();
@Autowired(required = false)
private Collection<IDialect> dialects = Collections.emptySet();
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
for (ITemplateResolver templateResolver : this.templateResolvers) {
engine.addTemplateResolver(templateResolver);
}
for (IDialect dialect : this.dialects) {
engine.addDialect(dialect);
}
return engine;
}
}
@Configuration
@ConditionalOnClass(name = "nz.net.ultraq.thymeleaf.LayoutDialect")
protected static class ThymeleafWebLayoutConfiguration {
@Bean
public LayoutDialect layoutDialect() {
return new LayoutDialect();
}
}
@Configuration
@ConditionalOnClass({ Servlet.class })
protected static class ThymeleafViewResolverConfiguration {
@Autowired
private SpringTemplateEngine templateEngine;
@Bean
@ConditionalOnMissingBean(name = "thymeleafViewResolver")
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(this.templateEngine);
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
}
@Configuration
@ConditionalOnClass({ SpringSecurityDialect.class })
protected static class ThymeleafSecurityDialectConfiguration {
@Bean
public SpringSecurityDialect securityDialect() {
return new SpringSecurityDialect();
}
}
}

View File

@@ -0,0 +1,137 @@
/*
* 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.boot.config.web;
import javax.servlet.Servlet;
import org.apache.catalina.startup.Tomcat;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.Loader;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.config.web.EmbeddedServletContainerAutoConfiguration.EmbeddedServletContainerCustomizerBeanPostProcessorRegistrar;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.boot.strap.context.condition.SearchStrategy;
import org.springframework.boot.strap.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
import org.springframework.boot.strap.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.strap.context.embedded.ServletContextInitializer;
import org.springframework.boot.strap.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.strap.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.web.servlet.DispatcherServlet;
/**
* {@link EnableAutoConfiguration Auto-configuration} for an embedded servlet containers.
*
* @author Phillip Webb
* @author Dave Syer
*/
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@Import(EmbeddedServletContainerCustomizerBeanPostProcessorRegistrar.class)
public class EmbeddedServletContainerAutoConfiguration {
/**
* Add the {@link DispatcherServlet} unless the user has defined their own
* {@link ServletContextInitializer}s.
*/
@ConditionalOnClass(DispatcherServlet.class)
public static class DispatcherServletConfiguration {
@Bean
@ConditionalOnMissingBean(value = { ServletContextInitializer.class,
Servlet.class }, search = SearchStrategy.CURRENT)
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
}
/**
* Nested configuration for if Tomcat is being used.
*/
@Configuration
@ConditionalOnClass({ Servlet.class, Tomcat.class })
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedTomcat {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory();
}
}
/**
* Nested configuration if Jetty is being used.
*/
@Configuration
@ConditionalOnClass({ Servlet.class, Server.class, Loader.class })
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedJetty {
@Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
return new JettyEmbeddedServletContainerFactory();
}
}
/**
* Registers a {@link EmbeddedServletContainerCustomizerBeanPostProcessor}. Registered
* via {@link ImportBeanDefinitionRegistrar} for early registration.
*/
public static class EmbeddedServletContainerCustomizerBeanPostProcessorRegistrar
implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
private ConfigurableListableBeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof ConfigurableListableBeanFactory) {
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
if (this.beanFactory != null
&& this.beanFactory.getBeansOfType(
EmbeddedServletContainerCustomizerBeanPostProcessor.class)
.size() == 0) {
BeanDefinition beanDefinition = new RootBeanDefinition(
EmbeddedServletContainerCustomizerBeanPostProcessor.class);
registry.registerBeanDefinition(
"embeddedServletContainerCustomizerBeanPostProcessor",
beanDefinition);
}
}
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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.boot.config.web;
import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.context.condition.ConditionalOnBean;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.embedded.EmbeddedWebApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
/**
* {@link EnableAutoConfiguration Auto-configuration} for multi-part uploads. Adds a
* {@link StandardServletMultipartResolver} when a {@link MultipartConfigElement} bean is
* defined. The {@link EmbeddedWebApplicationContext} will associated the
* {@link MultipartConfigElement} bean to any {@link Servlet} beans.
*
* @author Greg Turnquist
*/
@Configuration
@ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class })
@ConditionalOnBean(MultipartConfigElement.class)
public class MultipartAutoConfiguration {
@Bean
public StandardServletMultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.boot.config.web;
import org.springframework.beans.BeansException;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.boot.strap.context.embedded.ConfigurableEmbeddedServletContainerFactory;
import org.springframework.boot.strap.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.strap.context.embedded.properties.ServerProperties;
import org.springframework.boot.strap.context.properties.EnableConfigurationProperties;
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.Assert;
import org.springframework.util.StringUtils;
/**
* {@link EnableAutoConfiguration Auto-configuration} that configures the
* {@link ConfigurableEmbeddedServletContainerFactory} from a {@link ServerProperties}
* bean.
*
* @author Dave Syer
*/
@Configuration
@EnableConfigurationProperties
public class ServerPropertiesAutoConfiguration implements ApplicationContextAware,
EmbeddedServletContainerCustomizer {
private ApplicationContext applicationContext;
@Bean(name = "org.springframework.boot.strap.context.embedded.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) {
String[] serverPropertiesBeans = this.applicationContext
.getBeanNamesForType(ServerProperties.class);
Assert.state(
serverPropertiesBeans.length == 1,
"Multiple ServerProperties beans registered "
+ StringUtils.arrayToCommaDelimitedString(serverPropertiesBeans));
}
}

View File

@@ -0,0 +1,159 @@
/*
* 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.boot.config.web;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
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.boot.config.AutoConfigureAfter;
import org.springframework.boot.config.EnableAutoConfiguration;
import org.springframework.boot.strap.context.condition.ConditionalOnBean;
import org.springframework.boot.strap.context.condition.ConditionalOnClass;
import org.springframework.boot.strap.context.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.core.io.Resource;
import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.servlet.view.BeanNameViewResolver;
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,
WebMvcConfigurerAdapter.class })
@ConditionalOnMissingBean({ HandlerAdapter.class })
@Order(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class)
public class WebMvcAutoConfiguration {
// Defined as a nested config to ensure WebMvcConfigurerAdapter it not read when not
// on the classpath
@EnableWebMvc
public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
@Autowired
private ListableBeanFactory beanFactory;
@ConditionalOnBean(View.class)
@Bean
public BeanNameViewResolver beanNameViewResolver() {
BeanNameViewResolver resolver = new BeanNameViewResolver();
resolver.setOrder(0);
return resolver;
}
@ConditionalOnBean(View.class)
@Bean
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(beanFactory
.getBean(ContentNegotiationManager.class));
return resolver;
}
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addFormatters(FormatterRegistry registry) {
for (Converter<?, ?> converter : getBeansOfType(Converter.class)) {
registry.addConverter(converter);
}
for (GenericConverter converter : getBeansOfType(GenericConverter.class)) {
registry.addConverter(converter);
}
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) {
registry.addResourceHandler("/resources/**").addResourceLocations("/",
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/public/", "classpath:/static/");
registry.addResourceHandler("/**").addResourceLocations("/",
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/");
}
@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
protected ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
requestHandler.setLocations(Arrays
.<Resource> asList(new ClassPathResource("/")));
return requestHandler;
}
}
}
@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new HiddenHttpMethodFilter();
}
}

View File

@@ -0,0 +1,15 @@
# Auto Configure
org.springframework.boot.config.EnableAutoConfiguration=\
org.springframework.boot.config.MessageSourceAutoConfiguration,\
org.springframework.boot.config.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.config.batch.BatchAutoConfiguration,\
org.springframework.boot.config.data.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.config.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.config.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.config.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.config.reactor.ReactorAutoConfiguration,\
org.springframework.boot.config.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.config.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.config.web.ServerPropertiesAutoConfiguration,\
org.springframework.boot.config.web.MultipartAutoConfiguration,\
org.springframework.boot.config.web.WebMvcAutoConfiguration

View File

@@ -0,0 +1,36 @@
/*
* 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.boot.config;
import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import org.springframework.boot.strap.SimpleMainTests;
import org.springframework.boot.strap.context.embedded.jetty.JettyEmbeddedServletContainerFactoryTests;
/**
* A test suite for probing weird ordering problems in the tests.
*
* @author Dave Syer
*/
@RunWith(Suite.class)
@SuiteClasses({ SimpleMainTests.class, JettyEmbeddedServletContainerFactoryTests.class })
@Ignore
public class AdhocTestSuite {
}

View File

@@ -0,0 +1,107 @@
/*
* 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.boot.config;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.config.AutoConfigurationSorter;
import org.springframework.boot.config.AutoConfigureAfter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.DefaultResourceLoader;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link AutoConfigurationSorter}.
*
* @author Phillip Webb
*/
public class AutoConfigurationSorterTest {
private static final String LOWEST = OrderLowest.class.getName();
private static final String HIGHEST = OrderHighest.class.getName();
private static final String A = AutoConfigureA.class.getName();
private static final String B = AutoConfigureB.class.getName();
private static final String C = AutoConfigureC.class.getName();
private static final String D = AutoConfigureD.class.getName();
@Rule
public ExpectedException thrown = ExpectedException.none();
private AutoConfigurationSorter sorter;
@Before
public void setup() {
this.sorter = new AutoConfigurationSorter(new DefaultResourceLoader());
}
@Test
public void byOrderAnnotation() throws Exception {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(LOWEST,
HIGHEST));
assertThat(actual, equalTo(Arrays.asList(HIGHEST, LOWEST)));
}
@Test
public void byAutoConfigureAfter() throws Exception {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A, B, C));
assertThat(actual, equalTo(Arrays.asList(C, B, A)));
}
@Test
public void byAutoConfigureAfterWithMissing() throws Exception {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A, B));
assertThat(actual, equalTo(Arrays.asList(B, A)));
}
@Test
public void byAutoConfigureAfterWithCycle() throws Exception {
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Cycle");
this.sorter.getInPriorityOrder(Arrays.asList(A, B, C, D));
}
@Order(Ordered.LOWEST_PRECEDENCE)
public static class OrderLowest {
}
@Order(Ordered.HIGHEST_PRECEDENCE)
public static class OrderHighest {
}
@AutoConfigureAfter(AutoConfigureB.class)
public static class AutoConfigureA {
}
@AutoConfigureAfter({ AutoConfigureC.class, AutoConfigureD.class })
public static class AutoConfigureB {
}
public static class AutoConfigureC {
}
@AutoConfigureAfter(AutoConfigureA.class)
public static class AutoConfigureD {
}
}

View File

@@ -0,0 +1,30 @@
/*
* 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.boot.config;
import org.springframework.boot.config.ComponentScanDetector;
import org.springframework.context.annotation.Import;
/**
* Simple configuration to import {@link ComponentScanDetector} for tests.
*
* @author Phillip Webb
*/
@Import(ComponentScanDetector.class)
public class ComponentScanDetectorConfiguration {
}

View File

@@ -0,0 +1,64 @@
/*
* 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.boot.config;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.junit.Test;
import org.springframework.boot.config.MessageSourceAutoConfiguration;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.MapPropertySource;
import static org.junit.Assert.assertEquals;
/**
* Tests for {@link MessageSourceAutoConfiguration}.
*
* @author Dave Syer
*/
public class MessageSourceAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
@Test
public void testDefaultMessageSource() throws Exception {
this.context = new AnnotationConfigApplicationContext();
this.context.register(MessageSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertEquals("Foo message",
this.context.getMessage("foo", null, "Foo message", Locale.UK));
}
@Test
public void testMessageSourceCreated() throws Exception {
this.context = new AnnotationConfigApplicationContext();
this.context.register(MessageSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("spring.messages.basename", "test/messages");
this.context.getEnvironment().getPropertySources()
.addFirst(new MapPropertySource("test", map));
this.context.refresh();
assertEquals("bar",
this.context.getMessage("foo", null, "Foo message", Locale.UK));
}
}

View File

@@ -0,0 +1,64 @@
/*
* 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.boot.config;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.config.SpringJUnitTests.TestConfiguration;
import org.springframework.boot.strap.context.initializer.ConfigFileApplicationContextInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* @author Dave Syer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfiguration.class, initializers = ConfigFileApplicationContextInitializer.class)
public class SpringJUnitTests {
@Autowired
private ApplicationContext context;
@Value("${foo:spam}")
private String foo = "bar";
@Test
public void testContextCreated() {
assertNotNull(this.context);
}
@Test
public void testContextInitialized() {
assertEquals("bucket", this.foo);
}
@Configuration
@Import({ PropertyPlaceholderAutoConfiguration.class })
public static class TestConfiguration {
}
}

View File

@@ -0,0 +1,109 @@
/*
* 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.boot.config.batch;
import java.util.Collection;
import java.util.Collections;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionException;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.job.AbstractJob;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.config.batch.BatchAutoConfiguration;
import org.springframework.boot.config.batch.JobLauncherCommandLineRunner;
import org.springframework.boot.config.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import static org.junit.Assert.assertNotNull;
/**
* Tests for {@link BatchAutoConfiguration}.
*
* @author Dave Syer
*/
public class BatchAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
@Test
public void testDefaultContext() throws Exception {
this.context = new AnnotationConfigApplicationContext();
this.context.register(TestConfiguration.class, BatchAutoConfiguration.class,
EmbeddedDatabaseConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(JobLauncher.class));
}
@Test
public void testDefinesAndLaunchesJob() throws Exception {
this.context = new AnnotationConfigApplicationContext();
this.context.register(JobConfiguration.class, BatchAutoConfiguration.class,
EmbeddedDatabaseConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(JobLauncher.class));
this.context.getBean(JobLauncherCommandLineRunner.class).run();
assertNotNull(this.context.getBean(JobRepository.class).getLastJobExecution(
"job", new JobParameters()));
}
@EnableBatchProcessing
protected static class TestConfiguration {
}
@EnableBatchProcessing
protected static class JobConfiguration {
@Autowired
private JobRepository jobRepository;
@Bean
public Job job() {
AbstractJob job = new AbstractJob() {
@Override
public Collection<String> getStepNames() {
return Collections.emptySet();
}
@Override
public Step getStep(String stepName) {
return null;
}
@Override
protected void doExecute(JobExecution execution)
throws JobExecutionException {
execution.setStatus(BatchStatus.COMPLETED);
}
};
job.setJobRepository(this.jobRepository);
return job;
}
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.boot.config.batch;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.boot.config.batch.JobExecutionEvent;
import org.springframework.boot.config.batch.JobExecutionExitCodeGenerator;
import static org.junit.Assert.assertEquals;
/**
* Tests for {@link JobExecutionExitCodeGenerator}.
*
* @author Dave Syer
*/
public class JobExecutionExitCodeGeneratorTests {
private JobExecutionExitCodeGenerator generator = new JobExecutionExitCodeGenerator();
@Test
public void testExitCodeForRunning() {
this.generator.onApplicationEvent(new JobExecutionEvent(new JobExecution(0L)));
assertEquals(1, this.generator.getExitCode());
}
@Test
public void testExitCodeForCompleted() {
JobExecution execution = new JobExecution(0L);
execution.setStatus(BatchStatus.COMPLETED);
this.generator.onApplicationEvent(new JobExecutionEvent(execution));
assertEquals(0, this.generator.getExitCode());
}
@Test
public void testExitCodeForFailed() {
JobExecution execution = new JobExecution(0L);
execution.setStatus(BatchStatus.FAILED);
this.generator.onApplicationEvent(new JobExecutionEvent(execution));
assertEquals(5, this.generator.getExitCode());
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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.boot.config.data;
import javax.persistence.EntityManagerFactory;
import org.junit.Test;
import org.springframework.boot.config.ComponentScanDetectorConfiguration;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.config.data.JpaRepositoriesAutoConfiguration;
import org.springframework.boot.config.data.test.City;
import org.springframework.boot.config.data.test.CityRepository;
import org.springframework.boot.config.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.boot.config.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import static org.junit.Assert.assertNotNull;
/**
* Tests for {@link JpaRepositoriesAutoConfiguration}.
*
* @author Dave Syer
*/
public class JpaRepositoriesAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
@Test
public void testDefaultRepositoryConfiguration() throws Exception {
this.context = new AnnotationConfigApplicationContext();
this.context.register(TestConfiguration.class,
ComponentScanDetectorConfiguration.class,
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
JpaRepositoriesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(CityRepository.class));
assertNotNull(this.context.getBean(PlatformTransactionManager.class));
assertNotNull(this.context.getBean(EntityManagerFactory.class));
}
@Configuration
@ComponentScan(basePackageClasses = City.class)
protected static class TestConfiguration {
}
}

View File

@@ -0,0 +1,64 @@
/*
* 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.boot.config.data;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.config.data.JpaRepositoriesAutoConfiguration;
import org.springframework.boot.config.data.test.City;
import org.springframework.boot.config.data.test.CityRepository;
import org.springframework.boot.config.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.boot.config.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.repository.support.DomainClassConverter;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.junit.Assert.assertNotNull;
/**
* @author Dave Syer
*/
@Ignore
// FIXME until spring data commons 1.6.0, jpa 1.5.0 available
public class JpaWebAutoConfigurationTests {
private AnnotationConfigWebApplicationContext context;
@Test
public void testDefaultRepositoryConfiguration() throws Exception {
this.context = new AnnotationConfigWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(TestConfiguration.class,
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
JpaRepositoriesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(CityRepository.class));
assertNotNull(this.context.getBean(DomainClassConverter.class));
}
@Configuration
// @EnableSpringDataWebSupport
@ComponentScan(basePackageClasses = City.class)
protected static class TestConfiguration {
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.boot.config.data.test;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class City implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String state;
@Column(nullable = false)
private String country;
@Column(nullable = false)
private String map;
protected City() {
}
public City(String name, String country) {
super();
this.name = name;
this.country = country;
}
public String getName() {
return this.name;
}
public String getState() {
return this.state;
}
public String getCountry() {
return this.country;
}
public String getMap() {
return this.map;
}
@Override
public String toString() {
return getName() + "," + getState() + "," + getCountry();
}
}

View File

@@ -0,0 +1,32 @@
/*
* 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.boot.config.data.test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;
public interface CityRepository extends Repository<City, Long> {
Page<City> findAll(Pageable pageable);
Page<City> findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country,
Pageable pageable);
City findByNameAndCountryAllIgnoringCase(String name, String country);
}

View File

@@ -0,0 +1,44 @@
/*
* 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.boot.config.jdbc;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.boot.config.jdbc.BasicDataSourceConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertNotNull;
/**
* Tests for {@link BasicDataSourceConfiguration}.
*
* @author Dave Syer
*/
public class BasicDataSourceConfigurationTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test
public void testDataSourceExists() throws Exception {
this.context.register(BasicDataSourceConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
this.context.close();
}
}

View File

@@ -0,0 +1,121 @@
/*
* 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.boot.config.jdbc;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.junit.Test;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.config.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.MapPropertySource;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.util.ClassUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* Tests for {@link DataSourceAutoConfiguration}.
*
* @author Dave Syer
*/
public class DataSourceAutoConfigurationTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test
public void testDefaultDataSourceExists() throws Exception {
this.context.register(DataSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
}
@Test
public void testDefaultDataSourceCanBeOverridden() throws Exception {
this.context.register(TestDataSourceConfiguration.class,
DataSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
DataSource dataSource = this.context.getBean(DataSource.class);
assertTrue("DataSource is wrong type: " + dataSource,
dataSource instanceof BasicDataSource);
}
@Test
public void testJdbcTemplateExists() throws Exception {
this.context.register(DataSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
JdbcTemplate jdbcTemplate = this.context.getBean(JdbcTemplate.class);
assertNotNull(jdbcTemplate);
assertNotNull(jdbcTemplate.getDataSource());
}
@Test
public void testNamedParameterJdbcTemplateExists() throws Exception {
this.context.register(DataSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(NamedParameterJdbcOperations.class));
}
@Test
public void testDataSourceInitialized() throws Exception {
this.context.register(DataSourceAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("spring.database.schema",
ClassUtils.addResourcePathToPackagePath(getClass(), "schema.sql"));
this.context.getEnvironment().getPropertySources()
.addFirst(new MapPropertySource("test", map));
this.context.refresh();
DataSource dataSource = this.context.getBean(DataSource.class);
assertTrue(dataSource instanceof org.apache.tomcat.jdbc.pool.DataSource);
assertNotNull(dataSource);
JdbcOperations template = new JdbcTemplate(dataSource);
assertEquals(new Integer(0),
template.queryForObject("SELECT COUNT(*) from FOO", Integer.class));
}
@Configuration
static class TestDataSourceConfiguration {
private BasicDataSource pool;
@Bean
public DataSource dataSource() {
this.pool = new BasicDataSource();
this.pool.setDriverClassName("org.hsqldb.jdbcDriver");
this.pool.setUrl("jdbc:hsqldb:overridedb");
this.pool.setUsername("sa");
return this.pool;
}
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.boot.config.jdbc;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.boot.config.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.config.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Tests for {@link DataSourceTransactionManagerAutoConfiguration}.
*
* @author Dave Syer
*/
public class DataSourceTransactionManagerAutoConfigurationTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test
public void testDataSourceExists() throws Exception {
this.context.register(EmbeddedDatabaseConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
assertNotNull(this.context.getBean(DataSourceTransactionManager.class));
}
@Test
public void testNoDataSourceExists() throws Exception {
this.context.register(DataSourceTransactionManagerAutoConfiguration.class);
this.context.refresh();
assertEquals(0, this.context.getBeanNamesForType(DataSource.class).length);
assertEquals(
0,
this.context.getBeanNamesForType(DataSourceTransactionManager.class).length);
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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.boot.config.jdbc;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.boot.config.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertNotNull;
/**
* Tests for {@link EmbeddedDatabaseConfiguration}.
*
* @author Dave Syer
*/
public class EmbeddedDatabaseConfigurationTests {
private AnnotationConfigApplicationContext context;
@Test
public void testDefaultEmbeddedDatabase() throws Exception {
this.context = new AnnotationConfigApplicationContext();
this.context.register(EmbeddedDatabaseConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
this.context.close();
}
}

View File

@@ -0,0 +1,92 @@
/*
* 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.boot.config.jdbc;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.config.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.boot.config.jdbc.TomcatDataSourceConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.util.ReflectionUtils;
import static org.junit.Assert.assertNotNull;
/**
* Tests for {@link TomcatDataSourceConfiguration}.
*
* @author Dave Syer
*/
public class TomcatDataSourceConfigurationTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
private Map<Object, Object> old;
private Map<Object, Object> map;
@After
public void restore() {
if (this.map != null && this.old != null) {
this.map.putAll(this.old);
}
}
@Test
public void testDataSourceExists() throws Exception {
this.context.register(TomcatDataSourceConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
}
@Test(expected = BeanCreationException.class)
public void testBadUrl() throws Exception {
this.map = getField(EmbeddedDatabaseConfiguration.class, "EMBEDDED_DATABASE_URLS");
this.old = new HashMap<Object, Object>(this.map);
this.map.clear();
this.context.register(TomcatDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
}
@Test(expected = BeanCreationException.class)
public void testBadDriverClass() throws Exception {
this.map = getField(EmbeddedDatabaseConfiguration.class,
"EMBEDDED_DATABASE_DRIVER_CLASSES");
this.old = new HashMap<Object, Object>(this.map);
this.map.clear();
this.context.register(TomcatDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
}
@SuppressWarnings("unchecked")
public static <T> T getField(Class<?> target, String name) {
Field field = ReflectionUtils.findField(target, name, null);
ReflectionUtils.makeAccessible(field);
return (T) ReflectionUtils.getField(field, target);
}
}

View File

@@ -0,0 +1,138 @@
/*
* 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.boot.config.orm.jpa;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.config.ComponentScanDetectorConfiguration;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.config.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.config.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.boot.config.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.config.orm.jpa.test.City;
import org.springframework.boot.strap.TestUtils;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* Tests for {@link HibernateJpaAutoConfiguration}.
*
* @author Dave Syer
*/
public class HibernateJpaAutoConfigurationTests {
private ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void testEntityManagerCreated() throws Exception {
((AnnotationConfigApplicationContext) this.context).register(
ComponentScanDetectorConfiguration.class,
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
assertNotNull(this.context.getBean(JpaTransactionManager.class));
}
@Test
public void testDataSourceTransactionManagerNotCreated() throws Exception {
((AnnotationConfigApplicationContext) this.context).register(
ComponentScanDetectorConfiguration.class,
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
assertTrue(this.context.getBean("transactionManager") instanceof JpaTransactionManager);
}
@Test
public void testOpenEntityManagerInViewInterceptorCreated() throws Exception {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(ComponentScanDetectorConfiguration.class,
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class);
this.context = context;
this.context.refresh();
assertNotNull(this.context.getBean(OpenEntityManagerInViewInterceptor.class));
}
@Test
public void testOpenEntityManagerInViewInterceptorNotRegisteredWhenFilterPresent()
throws Exception {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(TestFilterConfiguration.class,
ComponentScanDetectorConfiguration.class,
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context = context;
this.context.refresh();
assertEquals(0, getInterceptorBeans().length);
}
@Test
public void testOpenEntityManagerInViewInterceptorNotRegisteredWhenExplicitlyOff()
throws Exception {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
TestUtils.addEnviroment(context, "spring.jpa.open_in_view:false");
context.register(TestConfiguration.class,
ComponentScanDetectorConfiguration.class,
EmbeddedDatabaseConfiguration.class, HibernateJpaAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context = context;
this.context.refresh();
assertEquals(0, getInterceptorBeans().length);
}
private String[] getInterceptorBeans() {
return this.context.getBeanNamesForType(OpenEntityManagerInViewInterceptor.class);
}
@ComponentScan(basePackageClasses = { City.class })
protected static class TestConfiguration {
}
@ComponentScan(basePackageClasses = { City.class })
@Configuration
protected static class TestFilterConfiguration {
@Bean
public OpenEntityManagerInViewFilter openEntityManagerInViewFilter() {
return new OpenEntityManagerInViewFilter();
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.boot.config.orm.jpa.test;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class City implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String state;
@Column(nullable = false)
private String country;
@Column(nullable = false)
private String map;
protected City() {
}
public City(String name, String country) {
super();
this.name = name;
this.country = country;
}
public String getName() {
return this.name;
}
public String getState() {
return this.state;
}
public String getCountry() {
return this.country;
}
public String getMap() {
return this.map;
}
@Override
public String toString() {
return getName() + "," + getState() + "," + getCountry();
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.boot.config.reactor;
import org.junit.Test;
import org.springframework.boot.config.reactor.ReactorAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import reactor.core.Reactor;
import static org.junit.Assert.assertNotNull;
/**
* @author Dave Syer
*/
public class ReactorAutoConfigurationTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test
public void reactorIsAvailable() {
this.context.register(ReactorAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(Reactor.class));
this.context.close();
}
}

View File

@@ -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.boot.config.thymeleaf;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.junit.Test;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.config.thymeleaf.ThymeleafAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.MapPropertySource;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.RequestContext;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring3.view.ThymeleafView;
import org.thymeleaf.spring3.view.ThymeleafViewResolver;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Tests for {@link ThymeleafAutoConfiguration}
* @author Dave Syer
*/
public class ThymeleafAutoConfigurationTests {
@Test
public void createFromConfigClass() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(ThymeleafAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("spring.template.mode", "XHTML");
map.put("spring.template.suffix", "");
context.getEnvironment().getPropertySources()
.addFirst(new MapPropertySource("test", map));
context.refresh();
TemplateEngine engine = context.getBean(TemplateEngine.class);
Context attrs = new Context(Locale.UK, Collections.singletonMap("foo", "bar"));
String result = engine.process("template.txt", attrs);
assertEquals("<html>bar</html>", result);
context.close();
}
@Test
public void createLayoutFromConfigClass() throws Exception {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(ThymeleafAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
MockServletContext servletContext = new MockServletContext();
context.setServletContext(servletContext);
context.refresh();
ThymeleafView view = (ThymeleafView) context.getBean(ThymeleafViewResolver.class)
.resolveViewName("view", Locale.UK);
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setAttribute(RequestContext.WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
view.render(Collections.singletonMap("foo", "bar"), request, response);
String result = response.getContentAsString();
assertTrue("Wrong result: " + result, result.contains("<title>Content</title>"));
assertTrue("Wrong result: " + result, result.contains("<span>bar</span>"));
context.close();
}
}

View File

@@ -0,0 +1,126 @@
/*
* 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.boot.config.web;
import javax.servlet.Servlet;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.config.web.EmbeddedServletContainerAutoConfiguration;
import org.springframework.boot.strap.context.condition.ConditionalOnExpression;
import org.springframework.boot.strap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.strap.context.embedded.ConfigurableEmbeddedServletContainerFactory;
import org.springframework.boot.strap.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.strap.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.strap.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);
}
}
}

View File

@@ -0,0 +1,217 @@
/*
* 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.boot.config.web;
import javax.servlet.MultipartConfigElement;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.config.web.EmbeddedServletContainerAutoConfiguration;
import org.springframework.boot.config.web.MultipartAutoConfiguration;
import org.springframework.boot.strap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.strap.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.strap.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
/**
* Tests for {@link MultipartAutoConfiguration}. Tests an empty configuration, no
* multipart configuration, and a multipart configuration (with both Jetty and Tomcat).
*
* @author Greg Turnquist
* @author Dave Syer
*/
public class MultipartAutoConfigurationTests {
private AnnotationConfigEmbeddedWebApplicationContext context;
@Rule
public ExpectedException thrown = ExpectedException.none();
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void containerWithNothing() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
ContainerWithNothing.class,
EmbeddedServletContainerAutoConfiguration.class,
MultipartAutoConfiguration.class);
DispatcherServlet servlet = this.context.getBean(DispatcherServlet.class);
assertNull(servlet.getMultipartResolver());
assertEquals(0,
this.context.getBeansOfType(StandardServletMultipartResolver.class)
.size());
assertEquals(0, this.context.getBeansOfType(MultipartResolver.class).size());
}
@Configuration
public static class ContainerWithNothing {
}
@Test
public void containerWithNoMultipartJettyConfiguration() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
ContainerWithNoMultipartJetty.class,
EmbeddedServletContainerAutoConfiguration.class,
MultipartAutoConfiguration.class);
DispatcherServlet servlet = this.context.getBean(DispatcherServlet.class);
assertNull(servlet.getMultipartResolver());
assertEquals(0,
this.context.getBeansOfType(StandardServletMultipartResolver.class)
.size());
assertEquals(0, this.context.getBeansOfType(MultipartResolver.class).size());
verifyServletWorks();
}
@Configuration
public static class ContainerWithNoMultipartJetty {
@Bean
JettyEmbeddedServletContainerFactory containerFactory() {
return new JettyEmbeddedServletContainerFactory();
}
@Bean
WebController controller() {
return new WebController();
}
}
@Test
public void containerWithNoMultipartTomcatConfiguration() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
ContainerWithNoMultipartTomcat.class,
EmbeddedServletContainerAutoConfiguration.class,
MultipartAutoConfiguration.class);
DispatcherServlet servlet = this.context.getBean(DispatcherServlet.class);
assertNull(servlet.getMultipartResolver());
assertEquals(0,
this.context.getBeansOfType(StandardServletMultipartResolver.class)
.size());
assertEquals(0, this.context.getBeansOfType(MultipartResolver.class).size());
verifyServletWorks();
}
@Test
public void containerWithAutomatedMultipartJettyConfiguration() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
ContainerWithEverythingJetty.class,
EmbeddedServletContainerAutoConfiguration.class,
MultipartAutoConfiguration.class);
this.context.getBean(MultipartConfigElement.class);
assertSame(this.context.getBean(DispatcherServlet.class).getMultipartResolver(),
this.context.getBean(StandardServletMultipartResolver.class));
verifyServletWorks();
}
@Test
public void containerWithAutomatedMultipartTomcatConfiguration() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
ContainerWithEverythingTomcat.class,
EmbeddedServletContainerAutoConfiguration.class,
MultipartAutoConfiguration.class);
this.context.getBean(MultipartConfigElement.class);
assertSame(this.context.getBean(DispatcherServlet.class).getMultipartResolver(),
this.context.getBean(StandardServletMultipartResolver.class));
verifyServletWorks();
}
private void verifyServletWorks() {
RestTemplate restTemplate = new RestTemplate();
assertEquals(restTemplate.getForObject("http://localhost:8080/", String.class),
"Hello");
}
@Configuration
public static class ContainerWithNoMultipartTomcat {
@Bean
TomcatEmbeddedServletContainerFactory containerFactory() {
return new TomcatEmbeddedServletContainerFactory();
}
@Bean
WebController controller() {
return new WebController();
}
}
@Configuration
public static class ContainerWithEverythingJetty {
@Bean
MultipartConfigElement multipartConfigElement() {
return new MultipartConfigElement("");
}
@Bean
JettyEmbeddedServletContainerFactory containerFactory() {
return new JettyEmbeddedServletContainerFactory();
}
@Bean
WebController webController() {
return new WebController();
}
}
@Configuration
@EnableWebMvc
public static class ContainerWithEverythingTomcat {
@Bean
MultipartConfigElement multipartConfigElement() {
return new MultipartConfigElement("");
}
@Bean
TomcatEmbeddedServletContainerFactory containerFactory() {
return new TomcatEmbeddedServletContainerFactory();
}
@Bean
WebController webController() {
return new WebController();
}
}
@Controller
public static class WebController {
@RequestMapping("/")
public @ResponseBody
String index() {
return "Hello";
}
}
}

View File

@@ -0,0 +1,138 @@
/*
* 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.boot.config.web;
import java.io.File;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mockito;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.config.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.config.web.ServerPropertiesAutoConfiguration;
import org.springframework.boot.strap.TestUtils;
import org.springframework.boot.strap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.strap.context.embedded.ConfigurableEmbeddedServletContainerFactory;
import org.springframework.boot.strap.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
import org.springframework.boot.strap.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.strap.context.embedded.properties.ServerProperties;
import org.springframework.boot.strap.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Tests for {@link ServerPropertiesAutoConfiguration}.
*
* @author Dave Syer
*/
public class ServerPropertiesAutoConfigurationTests {
private static ConfigurableEmbeddedServletContainerFactory containerFactory;
@Rule
public ExpectedException thrown = ExpectedException.none();
private AnnotationConfigEmbeddedWebApplicationContext context;
@Before
public void init() {
containerFactory = Mockito
.mock(ConfigurableEmbeddedServletContainerFactory.class);
}
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void createFromConfigClass() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(Config.class, ServerPropertiesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
TestUtils.addEnviroment(this.context, "server.port:9000");
this.context.refresh();
ServerProperties server = this.context.getBean(ServerProperties.class);
assertNotNull(server);
assertEquals(9000, server.getPort());
Mockito.verify(containerFactory).setPort(9000);
}
@Test
public void tomcatProperties() throws Exception {
containerFactory = Mockito.mock(TomcatEmbeddedServletContainerFactory.class);
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(Config.class, ServerPropertiesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
TestUtils.addEnviroment(this.context, "server.tomcat.basedir:target/foo");
this.context.refresh();
ServerProperties server = this.context.getBean(ServerProperties.class);
assertNotNull(server);
assertEquals(new File("target/foo"), server.getTomcat().getBasedir());
Mockito.verify(containerFactory).setPort(8080);
}
@Test
public void testAccidentalMultipleServerPropertiesBeans() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(Config.class, MutiServerPropertiesBeanConfig.class,
ServerPropertiesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.thrown.expect(BeanCreationException.class);
this.thrown.expectMessage("Multiple ServerProperties");
this.context.refresh();
}
@Configuration
protected static class Config {
@Bean
public EmbeddedServletContainerFactory containerFactory() {
return ServerPropertiesAutoConfigurationTests.containerFactory;
}
@Bean
public EmbeddedServletContainerCustomizerBeanPostProcessor embeddedServletContainerCustomizerBeanPostProcessor() {
return new EmbeddedServletContainerCustomizerBeanPostProcessor();
}
}
@Configuration
protected static class MutiServerPropertiesBeanConfig {
@Bean
public ServerProperties serverPropertiesOne() {
return new ServerProperties();
}
@Bean
public ServerProperties serverPropertiesTwo() {
return new ServerProperties();
}
}
}

View File

@@ -0,0 +1,123 @@
/*
* 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.boot.config.web;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.config.web.WebMvcAutoConfiguration;
import org.springframework.boot.strap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.strap.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
import org.springframework.boot.strap.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.strap.context.embedded.MockEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.AbstractView;
import static org.junit.Assert.assertEquals;
/**
* Tests for {@link WebMvcAutoConfiguration}.
*
* @author Phillip Webb
* @author Dave Syer
*/
public class WebMvcAutoConfigurationTests {
private static final MockEmbeddedServletContainerFactory containerFactory = new MockEmbeddedServletContainerFactory();
@Rule
public ExpectedException thrown = ExpectedException.none();
private AnnotationConfigEmbeddedWebApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void handerAdaptersCreated() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(Config.class, WebMvcAutoConfiguration.class);
this.context.refresh();
assertEquals(3, this.context.getBeanNamesForType(HandlerAdapter.class).length);
}
@Test
public void handerMappingsCreated() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(Config.class, WebMvcAutoConfiguration.class);
this.context.refresh();
assertEquals(6, this.context.getBeanNamesForType(HandlerMapping.class).length);
}
@Test
public void viewResolversCreatedIfViewsPresent() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(Config.class, ViewConfig.class,
WebMvcAutoConfiguration.class);
this.context.refresh();
assertEquals(2, this.context.getBeanNamesForType(ViewResolver.class).length);
}
@Configuration
protected static class ViewConfig {
@Bean
public View jsonView() {
return new AbstractView() {
@Override
protected void renderMergedOutputModel(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.getOutputStream().write("Hello World".getBytes());
}
};
}
}
@Configuration
protected static class Config {
@Bean
public EmbeddedServletContainerFactory containerFactory() {
return containerFactory;
}
@Bean
public EmbeddedServletContainerCustomizerBeanPostProcessor embeddedServletContainerCustomizerBeanPostProcessor() {
return new EmbeddedServletContainerCustomizerBeanPostProcessor();
}
}
}

View File

@@ -0,0 +1,4 @@
CREATE TABLE FOO (
id INTEGER IDENTITY PRIMARY KEY,
name VARCHAR(30),
);

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<title layout:fragment="title">Layout</title>
</head>
<body>
<div class="container">
<h1 layout:fragment="title">Layout</h1>
<div layout:fragment="content">
Fake content
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1 @@
<html th:text="${foo}">foo</html>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>
<definition name="*" template="layout">
<put-attribute name="content" value="content/{1}" />
<put-attribute name="title" value="title/{1}" />
</definition>
<definition name="content/*" template="{1} :: content" />
<definition name="title/*" template="{1} :: title" />
</tiles-definitions>

View File

@@ -0,0 +1,10 @@
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout" layout:decorator="layout">
<head>
<title layout:fragment="title">Content</title>
</head>
<body>
<div layout:fragment="content">
<span th:text="${foo}">foo</span>
</div>
</body>
</html>

View File

@@ -0,0 +1 @@
foo=bar