mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
Remove tangles from core + minor polish
This commit is contained in:
parent
2c05e9f150
commit
b838dc5422
@ -43,7 +43,7 @@ import org.springframework.zero.context.annotation.EnableAutoConfiguration;
|
||||
import org.springframework.zero.context.condition.ConditionalOnClass;
|
||||
import org.springframework.zero.context.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.zero.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
||||
import org.springframework.zero.context.embedded.ServerProperties;
|
||||
import org.springframework.zero.context.embedded.properties.ServerProperties;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} to enable Spring MVC to handle
|
||||
|
@ -20,7 +20,7 @@ import java.net.InetAddress;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.springframework.zero.context.embedded.ServerProperties;
|
||||
import org.springframework.zero.context.embedded.properties.ServerProperties;
|
||||
import org.springframework.zero.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
|
@ -27,7 +27,7 @@ import org.springframework.zero.context.annotation.EnableAutoConfiguration;
|
||||
import org.springframework.zero.context.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.zero.context.embedded.ConfigurableEmbeddedServletContainerFactory;
|
||||
import org.springframework.zero.context.embedded.EmbeddedServletContainerCustomizer;
|
||||
import org.springframework.zero.context.embedded.ServerProperties;
|
||||
import org.springframework.zero.context.embedded.properties.ServerProperties;
|
||||
import org.springframework.zero.context.properties.EnableConfigurationProperties;
|
||||
|
||||
/**
|
||||
|
@ -33,7 +33,7 @@ import org.springframework.zero.context.embedded.AnnotationConfigEmbeddedWebAppl
|
||||
import org.springframework.zero.context.embedded.ConfigurableEmbeddedServletContainerFactory;
|
||||
import org.springframework.zero.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
|
||||
import org.springframework.zero.context.embedded.EmbeddedServletContainerFactory;
|
||||
import org.springframework.zero.context.embedded.ServerProperties;
|
||||
import org.springframework.zero.context.embedded.properties.ServerProperties;
|
||||
import org.springframework.zero.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -59,13 +59,13 @@ public class PropertiesConfigurationFactory<T> implements FactoryBean<T>,
|
||||
|
||||
private PropertySources propertySources;
|
||||
|
||||
private T configuration;
|
||||
private T target;
|
||||
|
||||
private Validator validator;
|
||||
|
||||
private MessageSource messageSource;
|
||||
|
||||
private boolean initialized = false;
|
||||
private boolean hasBeenBound = false;
|
||||
|
||||
private String targetName;
|
||||
|
||||
@ -77,7 +77,7 @@ public class PropertiesConfigurationFactory<T> implements FactoryBean<T>,
|
||||
*/
|
||||
public PropertiesConfigurationFactory(T target) {
|
||||
Assert.notNull(target);
|
||||
this.configuration = target;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,7 +88,7 @@ public class PropertiesConfigurationFactory<T> implements FactoryBean<T>,
|
||||
@SuppressWarnings("unchecked")
|
||||
public PropertiesConfigurationFactory(Class<?> type) {
|
||||
Assert.notNull(type);
|
||||
this.configuration = (T) BeanUtils.instantiate(type);
|
||||
this.target = (T) BeanUtils.instantiate(type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,86 +165,15 @@ public class PropertiesConfigurationFactory<T> implements FactoryBean<T>,
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
Assert.state(this.properties != null || this.propertySources != null,
|
||||
"Properties or propertySources should not be null");
|
||||
|
||||
try {
|
||||
if (this.properties != null) {
|
||||
logger.trace("Properties:\n" + this.properties);
|
||||
}
|
||||
else {
|
||||
logger.trace("Property Sources: " + this.propertySources);
|
||||
}
|
||||
this.initialized = true;
|
||||
|
||||
RelaxedDataBinder dataBinder;
|
||||
if (this.targetName != null) {
|
||||
dataBinder = new RelaxedDataBinder(this.configuration, this.targetName);
|
||||
}
|
||||
else {
|
||||
dataBinder = new RelaxedDataBinder(this.configuration);
|
||||
}
|
||||
if (this.validator != null) {
|
||||
dataBinder.setValidator(this.validator);
|
||||
}
|
||||
if (this.conversionService != null) {
|
||||
dataBinder.setConversionService(this.conversionService);
|
||||
}
|
||||
dataBinder.setIgnoreInvalidFields(this.ignoreInvalidFields);
|
||||
dataBinder.setIgnoreUnknownFields(this.ignoreUnknownFields);
|
||||
customizeBinder(dataBinder);
|
||||
PropertyValues pvs;
|
||||
if (this.properties != null) {
|
||||
pvs = new MutablePropertyValues(this.properties);
|
||||
}
|
||||
else {
|
||||
pvs = new PropertySourcesPropertyValues(this.propertySources);
|
||||
}
|
||||
dataBinder.bind(pvs);
|
||||
|
||||
if (this.validator != null) {
|
||||
dataBinder.validate();
|
||||
BindingResult errors = dataBinder.getBindingResult();
|
||||
|
||||
if (errors.hasErrors()) {
|
||||
logger.error("Properties configuration failed validation");
|
||||
for (ObjectError error : errors.getAllErrors()) {
|
||||
logger.error(this.messageSource != null ? this.messageSource
|
||||
.getMessage(error, Locale.getDefault())
|
||||
+ " ("
|
||||
+ error
|
||||
+ ")" : error);
|
||||
}
|
||||
if (this.exceptionIfInvalid) {
|
||||
BindException summary = new BindException(errors);
|
||||
throw summary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BindException e) {
|
||||
if (this.exceptionIfInvalid) {
|
||||
throw e;
|
||||
}
|
||||
logger.error(
|
||||
"Failed to load Properties validation bean. Your Properties may be invalid.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dataBinder the data binder that will be used to bind and validate
|
||||
*/
|
||||
protected void customizeBinder(DataBinder dataBinder) {
|
||||
bindPropertiesToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
if (this.configuration == null) {
|
||||
if (this.target == null) {
|
||||
return Object.class;
|
||||
}
|
||||
return this.configuration.getClass();
|
||||
return this.target.getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -254,10 +183,80 @@ public class PropertiesConfigurationFactory<T> implements FactoryBean<T>,
|
||||
|
||||
@Override
|
||||
public T getObject() throws Exception {
|
||||
if (!this.initialized) {
|
||||
afterPropertiesSet();
|
||||
if (!this.hasBeenBound) {
|
||||
bindPropertiesToTarget();
|
||||
}
|
||||
return this.configuration;
|
||||
return this.target;
|
||||
}
|
||||
|
||||
public void bindPropertiesToTarget() throws BindException {
|
||||
Assert.state(this.properties != null || this.propertySources != null,
|
||||
"Properties or propertySources should not be null");
|
||||
try {
|
||||
if (logger.isTraceEnabled()) {
|
||||
if (this.properties != null) {
|
||||
logger.trace("Properties:\n" + this.properties);
|
||||
}
|
||||
else {
|
||||
logger.trace("Property Sources: " + this.propertySources);
|
||||
}
|
||||
}
|
||||
this.hasBeenBound = true;
|
||||
doBindPropertiesToTarget();
|
||||
}
|
||||
catch (BindException e) {
|
||||
if (this.exceptionIfInvalid) {
|
||||
throw e;
|
||||
}
|
||||
logger.error("Failed to load Properties validation bean. "
|
||||
+ "Your Properties may be invalid.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void doBindPropertiesToTarget() throws BindException {
|
||||
|
||||
RelaxedDataBinder dataBinder = (this.targetName != null ? new RelaxedDataBinder(
|
||||
this.target, this.targetName) : new RelaxedDataBinder(this.target));
|
||||
if (this.validator != null) {
|
||||
dataBinder.setValidator(this.validator);
|
||||
}
|
||||
if (this.conversionService != null) {
|
||||
dataBinder.setConversionService(this.conversionService);
|
||||
}
|
||||
dataBinder.setIgnoreInvalidFields(this.ignoreInvalidFields);
|
||||
dataBinder.setIgnoreUnknownFields(this.ignoreUnknownFields);
|
||||
customizeBinder(dataBinder);
|
||||
|
||||
PropertyValues propertyValues = (this.properties != null ? new MutablePropertyValues(
|
||||
this.properties)
|
||||
: new PropertySourcesPropertyValues(this.propertySources));
|
||||
dataBinder.bind(propertyValues);
|
||||
|
||||
if (this.validator != null) {
|
||||
validate(dataBinder);
|
||||
}
|
||||
}
|
||||
|
||||
private void validate(RelaxedDataBinder dataBinder) throws BindException {
|
||||
dataBinder.validate();
|
||||
BindingResult errors = dataBinder.getBindingResult();
|
||||
if (errors.hasErrors()) {
|
||||
logger.error("Properties configuration failed validation");
|
||||
for (ObjectError error : errors.getAllErrors()) {
|
||||
logger.error(this.messageSource != null ? this.messageSource.getMessage(
|
||||
error, Locale.getDefault()) + " (" + error + ")" : error);
|
||||
}
|
||||
if (this.exceptionIfInvalid) {
|
||||
BindException summary = new BindException(errors);
|
||||
throw summary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dataBinder the data binder that will be used to bind and validate
|
||||
*/
|
||||
protected void customizeBinder(DataBinder dataBinder) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.zero.context.embedded;
|
||||
package org.springframework.zero.context.embedded.properties;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetAddress;
|
||||
@ -24,6 +24,10 @@ import javax.validation.constraints.NotNull;
|
||||
import org.apache.catalina.valves.AccessLogValve;
|
||||
import org.apache.catalina.valves.RemoteIpValve;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.zero.context.embedded.ConfigurableEmbeddedServletContainerFactory;
|
||||
import org.springframework.zero.context.embedded.EmbeddedServletContainerCustomizer;
|
||||
import org.springframework.zero.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
|
||||
import org.springframework.zero.context.embedded.EmbeddedServletContainerFactory;
|
||||
import org.springframework.zero.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
||||
import org.springframework.zero.context.properties.ConfigurationProperties;
|
||||
|
@ -27,9 +27,9 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.env.PropertySources;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.zero.bind.PropertiesConfigurationFactory;
|
||||
import org.springframework.zero.context.properties.EnableConfigurationPropertiesImportSelector.ConfigurationPropertiesHolder;
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} to bind {@link PropertySources} to beans annotated with
|
||||
@ -89,44 +89,41 @@ public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProc
|
||||
throws BeansException {
|
||||
ConfigurationProperties annotation = AnnotationUtils.findAnnotation(
|
||||
bean.getClass(), ConfigurationProperties.class);
|
||||
Object target = bean;
|
||||
if (annotation != null || bean instanceof ConfigurationPropertiesHolder) {
|
||||
if (bean instanceof ConfigurationPropertiesHolder) {
|
||||
target = ((ConfigurationPropertiesHolder) bean).getTarget();
|
||||
}
|
||||
PropertiesConfigurationFactory<Object> factory = new PropertiesConfigurationFactory<Object>(
|
||||
target);
|
||||
factory.setPropertySources(this.propertySources);
|
||||
factory.setValidator(this.validator);
|
||||
// If no explicit conversion service is provided we add one so that (at least)
|
||||
// comma-separated arrays of convertibles can be bound automatically
|
||||
factory.setConversionService(this.conversionService == null ? getDefaultConversionService()
|
||||
: this.conversionService);
|
||||
String targetName = null;
|
||||
if (annotation != null) {
|
||||
factory.setIgnoreInvalidFields(annotation.ignoreInvalidFields());
|
||||
factory.setIgnoreUnknownFields(annotation.ignoreUnknownFields());
|
||||
targetName = "".equals(annotation.value()) ? (""
|
||||
.equals(annotation.name()) ? null : annotation.name())
|
||||
: annotation.value();
|
||||
}
|
||||
factory.setTargetName(targetName);
|
||||
try {
|
||||
target = factory.getObject(); // throwaway
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new BeanCreationException(beanName, "Could not bind", e);
|
||||
}
|
||||
postProcessAfterInitialization(bean, beanName, annotation);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private void postProcessAfterInitialization(Object bean, String beanName,
|
||||
ConfigurationProperties annotation) {
|
||||
Object target = (bean instanceof ConfigurationPropertiesHolder ? ((ConfigurationPropertiesHolder) bean)
|
||||
.getTarget() : bean);
|
||||
PropertiesConfigurationFactory<Object> factory = new PropertiesConfigurationFactory<Object>(
|
||||
target);
|
||||
factory.setPropertySources(this.propertySources);
|
||||
factory.setValidator(this.validator);
|
||||
// If no explicit conversion service is provided we add one so that (at least)
|
||||
// comma-separated arrays of convertibles can be bound automatically
|
||||
factory.setConversionService(this.conversionService == null ? getDefaultConversionService()
|
||||
: this.conversionService);
|
||||
if (annotation != null) {
|
||||
factory.setIgnoreInvalidFields(annotation.ignoreInvalidFields());
|
||||
factory.setIgnoreUnknownFields(annotation.ignoreUnknownFields());
|
||||
String targetName = (StringUtils.hasLength(annotation.value()) ? annotation
|
||||
.value() : annotation.name());
|
||||
if (StringUtils.hasLength(targetName)) {
|
||||
factory.setTargetName(targetName);
|
||||
}
|
||||
}
|
||||
try {
|
||||
factory.bindPropertiesToTarget();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new BeanCreationException(beanName, "Could not bind properties", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private ConversionService getDefaultConversionService() {
|
||||
if (!this.initialized && this.beanFactory instanceof ListableBeanFactory) {
|
||||
for (Converter<?, ?> converter : ((ListableBeanFactory) this.beanFactory)
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.zero.context.properties;
|
||||
|
||||
/**
|
||||
* Properties holder registered by {@link EnableConfigurationPropertiesImportSelector} to
|
||||
* be picked up by {@link ConfigurationPropertiesBindingPostProcessor}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
class ConfigurationPropertiesHolder {
|
||||
|
||||
private Object target;
|
||||
|
||||
public ConfigurationPropertiesHolder(Object target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public Object getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@ package org.springframework.zero.context.properties;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
@ -67,17 +68,7 @@ class EnableConfigurationPropertiesImportSelector implements ImportSelector {
|
||||
for (Class<?> type : types) {
|
||||
String name = type.getName();
|
||||
if (!registry.containsBeanDefinition(name)) {
|
||||
registry.registerBeanDefinition(name, BeanDefinitionBuilder
|
||||
.genericBeanDefinition(type).getBeanDefinition());
|
||||
ConfigurationProperties properties = AnnotationUtils.findAnnotation(
|
||||
type, ConfigurationProperties.class);
|
||||
if (properties == null) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(ConfigurationPropertiesHolder.class);
|
||||
builder.addConstructorArgReference(name);
|
||||
registry.registerBeanDefinition(name + ".HOLDER",
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
registerBeanDefinition(registry, type, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,18 +85,25 @@ class EnableConfigurationPropertiesImportSelector implements ImportSelector {
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
private void registerBeanDefinition(BeanDefinitionRegistry registry,
|
||||
Class<?> type, String name) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(type);
|
||||
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
|
||||
registry.registerBeanDefinition(name, beanDefinition);
|
||||
|
||||
public static class ConfigurationPropertiesHolder {
|
||||
|
||||
private Object target;
|
||||
|
||||
public ConfigurationPropertiesHolder(Object target) {
|
||||
this.target = target;
|
||||
ConfigurationProperties properties = AnnotationUtils.findAnnotation(type,
|
||||
ConfigurationProperties.class);
|
||||
if (properties == null) {
|
||||
registerPropertiesHolder(registry, name);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getTarget() {
|
||||
return this.target;
|
||||
private void registerPropertiesHolder(BeanDefinitionRegistry registry, String name) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(ConfigurationPropertiesHolder.class);
|
||||
builder.addConstructorArgReference(name);
|
||||
registry.registerBeanDefinition(name + ".HOLDER", builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.zero.context.embedded;
|
||||
package org.springframework.zero.context.embedded.properties;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Collections;
|
||||
@ -24,6 +24,7 @@ import java.util.Map;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.zero.bind.RelaxedDataBinder;
|
||||
import org.springframework.zero.context.embedded.properties.ServerProperties;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
Loading…
Reference in New Issue
Block a user