mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-15 01:07:30 +08:00
Polish
This commit is contained in:
parent
db41fb16c0
commit
6193b640a4
@ -6,7 +6,6 @@ something, or simply want to hack on the code this document should help you get
|
||||
|
||||
|
||||
== Using GitHub issues
|
||||
|
||||
We use GitHub issues to track bugs and enhancements. If you have a general usage question
|
||||
please ask on http://stackoverflow.com[Stack Overflow]. The Spring Boot team and the
|
||||
broader community monitor the http://stackoverflow.com/tags/spring-boot[`spring-boot`]
|
||||
|
@ -66,8 +66,8 @@ import org.springframework.lang.UsesJava7;
|
||||
@Configuration
|
||||
@AutoConfigureBefore(EndpointAutoConfiguration.class)
|
||||
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, CacheAutoConfiguration.class,
|
||||
MetricRepositoryAutoConfiguration.class, CacheStatisticsAutoConfiguration.class,
|
||||
IntegrationAutoConfiguration.class })
|
||||
MetricRepositoryAutoConfiguration.class, CacheStatisticsAutoConfiguration.class,
|
||||
IntegrationAutoConfiguration.class })
|
||||
public class PublicMetricsAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
|
@ -42,8 +42,8 @@ public class ShellProperties {
|
||||
private static Log logger = LogFactory.getLog(ShellProperties.class);
|
||||
|
||||
/**
|
||||
* Authentication type. Auto-detected according to the environment (i.e. if
|
||||
* Spring Security is available, "spring" is used by default).
|
||||
* Authentication type. Auto-detected according to the environment (i.e. if Spring
|
||||
* Security is available, "spring" is used by default).
|
||||
*/
|
||||
private String auth = "simple";
|
||||
|
||||
|
@ -16,14 +16,6 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure;
|
||||
|
||||
import static org.hamcrest.Matchers.hasKey;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
@ -67,6 +59,14 @@ import org.springframework.util.SocketUtils;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import static org.hamcrest.Matchers.hasKey;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link PublicMetricsAutoConfiguration}.
|
||||
*
|
||||
@ -150,7 +150,7 @@ public class PublicMetricsAutoConfigurationTests {
|
||||
jdbcTemplate.execute(new ConnectionCallback<Void>() {
|
||||
@Override
|
||||
public Void doInConnection(Connection connection) throws SQLException,
|
||||
DataAccessException {
|
||||
DataAccessException {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -246,7 +246,8 @@ public class PublicMetricsAutoConfigurationTests {
|
||||
}
|
||||
context.register(DataSourcePoolMetadataProvidersConfiguration.class,
|
||||
CacheStatisticsAutoConfiguration.class,
|
||||
PublicMetricsAutoConfiguration.class, MockEmbeddedServletContainerFactory.class);
|
||||
PublicMetricsAutoConfiguration.class,
|
||||
MockEmbeddedServletContainerFactory.class);
|
||||
context.refresh();
|
||||
this.context = context;
|
||||
}
|
||||
|
@ -16,9 +16,6 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure;
|
||||
|
||||
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
|
||||
import static org.springframework.util.StringUtils.trimAllWhitespace;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Iterator;
|
||||
@ -44,6 +41,9 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
|
||||
import static org.springframework.util.StringUtils.trimAllWhitespace;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for {@link MessageSource}.
|
||||
*
|
||||
@ -52,7 +52,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(value=MessageSource.class, search=SearchStrategy.CURRENT)
|
||||
@ConditionalOnMissingBean(value = MessageSource.class, search = SearchStrategy.CURRENT)
|
||||
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
|
||||
@Conditional(ResourceBundleCondition.class)
|
||||
@EnableConfigurationProperties
|
||||
@ -81,8 +81,8 @@ public class MessageSourceAutoConfiguration {
|
||||
|
||||
/**
|
||||
* Set whether to fall back to the system Locale if no files for a specific Locale
|
||||
* have been found. if this is turned off, the only fallback will be the default
|
||||
* file (e.g. "messages.properties" for basename "messages").
|
||||
* have been found. if this is turned off, the only fallback will be the default file
|
||||
* (e.g. "messages.properties" for basename "messages").
|
||||
*/
|
||||
private boolean fallbackToSystemLocale = true;
|
||||
|
||||
@ -91,7 +91,7 @@ public class MessageSourceAutoConfiguration {
|
||||
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
|
||||
if (StringUtils.hasText(this.basename)) {
|
||||
messageSource
|
||||
.setBasenames(commaDelimitedListToStringArray(trimAllWhitespace(this.basename)));
|
||||
.setBasenames(commaDelimitedListToStringArray(trimAllWhitespace(this.basename)));
|
||||
}
|
||||
if (this.encoding != null) {
|
||||
messageSource.setDefaultEncoding(this.encoding.name());
|
||||
@ -167,7 +167,7 @@ public class MessageSourceAutoConfiguration {
|
||||
private Resource[] getResources(ClassLoader classLoader, String name) {
|
||||
try {
|
||||
return new SkipPatternPathMatchingResourcePatternResolver(classLoader)
|
||||
.getResources("classpath*:" + name + "*.properties");
|
||||
.getResources("classpath*:" + name + "*.properties");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return NO_RESOURCES;
|
||||
@ -181,7 +181,7 @@ public class MessageSourceAutoConfiguration {
|
||||
* contain messages.properties.
|
||||
*/
|
||||
private static class SkipPatternPathMatchingResourcePatternResolver extends
|
||||
PathMatchingResourcePatternResolver {
|
||||
PathMatchingResourcePatternResolver {
|
||||
|
||||
private static final ClassLoader ROOT_CLASSLOADER;
|
||||
static {
|
||||
@ -198,14 +198,14 @@ public class MessageSourceAutoConfiguration {
|
||||
}
|
||||
|
||||
private static final String[] SKIPPED = { "aspectjweaver-", "hibernate-core-",
|
||||
"hsqldb-", "jackson-annotations-", "jackson-core-", "jackson-databind-",
|
||||
"javassist-", "snakeyaml-", "spring-aop-", "spring-beans-",
|
||||
"spring-boot-", "spring-boot-actuator-", "spring-boot-autoconfigure-",
|
||||
"spring-core-", "spring-context-", "spring-data-commons-",
|
||||
"spring-expression-", "spring-jdbc-", "spring-orm-", "spring-tx-",
|
||||
"spring-web-", "spring-webmvc-", "tomcat-embed-", "joda-time-",
|
||||
"hibernate-entitymanager-", "hibernate-validator-", "logback-classic-",
|
||||
"logback-core-", "thymeleaf-" };
|
||||
"hsqldb-", "jackson-annotations-", "jackson-core-", "jackson-databind-",
|
||||
"javassist-", "snakeyaml-", "spring-aop-", "spring-beans-",
|
||||
"spring-boot-", "spring-boot-actuator-", "spring-boot-autoconfigure-",
|
||||
"spring-core-", "spring-context-", "spring-data-commons-",
|
||||
"spring-expression-", "spring-jdbc-", "spring-orm-", "spring-tx-",
|
||||
"spring-web-", "spring-webmvc-", "tomcat-embed-", "joda-time-",
|
||||
"hibernate-entitymanager-", "hibernate-validator-", "logback-classic-",
|
||||
"logback-core-", "thymeleaf-" };
|
||||
|
||||
public SkipPatternPathMatchingResourcePatternResolver(ClassLoader classLoader) {
|
||||
super(classLoader);
|
||||
|
@ -63,9 +63,8 @@ public @interface SpringBootApplication {
|
||||
String[] excludeName() default {};
|
||||
|
||||
/**
|
||||
* Base packages to scan for annotated components.
|
||||
* <p>Use {@link #scanBasePackageClasses} for a type-safe alternative to
|
||||
* String-based package names.
|
||||
* Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
|
||||
* for a type-safe alternative to String-based package names.
|
||||
* @return base packages to scan
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@ -73,10 +72,11 @@ public @interface SpringBootApplication {
|
||||
String[] scanBasePackages() default {};
|
||||
|
||||
/**
|
||||
* Type-safe alternative to {@link #scanBasePackages} for specifying the packages
|
||||
* to scan for annotated components. The package of each class specified will be scanned.
|
||||
* <p>Consider creating a special no-op marker class or interface in each package
|
||||
* that serves no purpose other than being referenced by this attribute.
|
||||
* Type-safe alternative to {@link #scanBasePackages} for specifying the packages to
|
||||
* scan for annotated components. The package of each class specified will be scanned.
|
||||
* <p>
|
||||
* Consider creating a special no-op marker class or interface in each package that
|
||||
* serves no purpose other than being referenced by this attribute.
|
||||
* @return base packages to scan
|
||||
* @since 1.3.0
|
||||
*/
|
||||
|
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.jdbc;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
@ -48,8 +49,8 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
|
||||
private String name = "testdb";
|
||||
|
||||
/**
|
||||
* Fully qualified name of the connection pool implementation to use. By default,
|
||||
* it is auto-detected from the classpath.
|
||||
* Fully qualified name of the connection pool implementation to use. By default, it
|
||||
* is auto-detected from the classpath.
|
||||
*/
|
||||
private Class<? extends DataSource> type;
|
||||
|
||||
|
@ -134,8 +134,8 @@ public class JpaProperties {
|
||||
|
||||
/**
|
||||
* DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto"
|
||||
* property. Default to "create-drop" when using an embedded database,
|
||||
* "none" otherwise.
|
||||
* property. Default to "create-drop" when using an embedded database, "none"
|
||||
* otherwise.
|
||||
*/
|
||||
private String ddlAuto;
|
||||
|
||||
|
@ -69,7 +69,6 @@ public class AuthenticationManagerConfiguration {
|
||||
private static Log logger = LogFactory
|
||||
.getLog(AuthenticationManagerConfiguration.class);
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Autowired
|
||||
private List<SecurityPrerequisite> dependencies;
|
||||
|
||||
@ -112,7 +111,7 @@ public class AuthenticationManagerConfiguration {
|
||||
*/
|
||||
@Order(Ordered.LOWEST_PRECEDENCE - 100)
|
||||
private static class SpringBootAuthenticationConfigurerAdapter extends
|
||||
GlobalAuthenticationConfigurerAdapter {
|
||||
GlobalAuthenticationConfigurerAdapter {
|
||||
|
||||
private final SecurityProperties securityProperties;
|
||||
|
||||
@ -152,7 +151,7 @@ public class AuthenticationManagerConfiguration {
|
||||
* </ul>
|
||||
*/
|
||||
private static class DefaultInMemoryUserDetailsManagerConfigurer extends
|
||||
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> {
|
||||
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> {
|
||||
|
||||
private final SecurityProperties securityProperties;
|
||||
|
||||
@ -169,7 +168,7 @@ public class AuthenticationManagerConfiguration {
|
||||
User user = this.securityProperties.getUser();
|
||||
if (user.isDefaultPassword()) {
|
||||
logger.info("\n\nUsing default security password: " + user.getPassword()
|
||||
+ "\n");
|
||||
+ "\n");
|
||||
}
|
||||
Set<String> roles = new LinkedHashSet<String>(user.getRole());
|
||||
withUser(user.getName()).password(user.getPassword()).roles(
|
||||
@ -197,7 +196,7 @@ public class AuthenticationManagerConfiguration {
|
||||
*/
|
||||
@Component
|
||||
protected static class AuthenticationManagerConfigurationListener implements
|
||||
SmartInitializingSingleton {
|
||||
SmartInitializingSingleton {
|
||||
|
||||
@Autowired
|
||||
private AuthenticationEventPublisher eventPublisher;
|
||||
@ -219,7 +218,7 @@ public class AuthenticationManagerConfiguration {
|
||||
private void configureAuthenticationManager(AuthenticationManager manager) {
|
||||
if (manager instanceof ProviderManager) {
|
||||
((ProviderManager) manager)
|
||||
.setAuthenticationEventPublisher(this.eventPublisher);
|
||||
.setAuthenticationEventPublisher(this.eventPublisher);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
|
||||
@EnableConfigurationProperties
|
||||
@Import({ SpringBootWebSecurityConfiguration.class,
|
||||
AuthenticationManagerConfiguration.class,
|
||||
BootGlobalAuthenticationConfiguration.class,
|
||||
SecurityDataConfiguration.class })
|
||||
BootGlobalAuthenticationConfiguration.class, SecurityDataConfiguration.class })
|
||||
public class SecurityAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.security;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
@ -39,4 +40,4 @@ public class SecurityDataConfiguration {
|
||||
return new SecurityEvaluationContextExtension();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.security;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
@ -44,16 +45,17 @@ import org.springframework.security.web.context.AbstractSecurityWebApplicationIn
|
||||
@AutoConfigureAfter(SpringBootWebSecurityConfiguration.class)
|
||||
public class SecurityFilterAutoConfiguration {
|
||||
|
||||
private static final String DEFAULT_FILTER_NAME = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
|
||||
@ConditionalOnBean(name = DEFAULT_FILTER_NAME)
|
||||
public FilterRegistrationBean securityFilterChainRegistration(
|
||||
@Qualifier(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME) Filter securityFilter,
|
||||
@Qualifier(DEFAULT_FILTER_NAME) Filter securityFilter,
|
||||
SecurityProperties securityProperties) {
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean(securityFilter);
|
||||
registration.setOrder(securityProperties.getFilterOrder());
|
||||
registration
|
||||
.setName(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
|
||||
registration.setName(DEFAULT_FILTER_NAME);
|
||||
return registration;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -40,8 +40,7 @@ public class SecurityProperties implements SecurityPrerequisite {
|
||||
* useful place to put user-defined access rules if you want to override the default
|
||||
* access rules.
|
||||
*/
|
||||
public static final int ACCESS_OVERRIDE_ORDER = SecurityProperties.BASIC_AUTH_ORDER
|
||||
- 2;
|
||||
public static final int ACCESS_OVERRIDE_ORDER = SecurityProperties.BASIC_AUTH_ORDER - 2;
|
||||
|
||||
/**
|
||||
* Order applied to the WebSecurityConfigurerAdapter that is used to configure basic
|
||||
@ -62,8 +61,7 @@ public class SecurityProperties implements SecurityPrerequisite {
|
||||
* other filters registered with the container). There is no connection between this
|
||||
* and the <code>@Order</code> on a WebSecurityConfigurer.
|
||||
*/
|
||||
public static final int DEFAULT_FILTER_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER
|
||||
- 100;
|
||||
public static final int DEFAULT_FILTER_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 100;
|
||||
|
||||
/**
|
||||
* Enable secure channel for all requests.
|
||||
|
@ -31,9 +31,10 @@ import org.springframework.context.annotation.Conditional;
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Conditional(OnEnabledResourceChainCondition.class)
|
||||
public @interface ConditionalOnEnabledResourceChain {
|
||||
|
||||
}
|
||||
|
@ -34,14 +34,16 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
class OnEnabledResourceChainCondition extends SpringBootCondition {
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
ConfigurableEnvironment environment = (ConfigurableEnvironment) context.getEnvironment();
|
||||
ResourceProperties resourceProperties = new ResourceProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(resourceProperties, "spring.resources");
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
ConfigurableEnvironment environment = (ConfigurableEnvironment) context
|
||||
.getEnvironment();
|
||||
ResourceProperties properties = new ResourceProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(properties, "spring.resources");
|
||||
binder.bind(new PropertySourcesPropertyValues(environment.getPropertySources()));
|
||||
|
||||
Boolean match = resourceProperties.getChain().getEnabled();
|
||||
return new ConditionOutcome(match, "Resource chain is " + (match ? "enabled" : "disabled" + ")"));
|
||||
Boolean match = properties.getChain().getEnabled();
|
||||
return new ConditionOutcome(match, "Resource chain is "
|
||||
+ (match ? "enabled" : "disabled" + ")"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
|
||||
}
|
||||
if (container instanceof TomcatEmbeddedServletContainerFactory) {
|
||||
getTomcat()
|
||||
.customizeTomcat((TomcatEmbeddedServletContainerFactory) container);
|
||||
.customizeTomcat((TomcatEmbeddedServletContainerFactory) container);
|
||||
}
|
||||
if (container instanceof UndertowEmbeddedServletContainerFactory) {
|
||||
getUndertow().customizeUndertow(
|
||||
@ -1015,7 +1015,7 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
|
||||
* configuration.
|
||||
*/
|
||||
private static class SessionConfiguringInitializer implements
|
||||
ServletContextInitializer {
|
||||
ServletContextInitializer {
|
||||
|
||||
private final Session session;
|
||||
|
||||
|
@ -96,7 +96,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication
|
||||
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
|
||||
WebMvcConfigurerAdapter.class })
|
||||
WebMvcConfigurerAdapter.class })
|
||||
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
|
||||
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
|
||||
@AutoConfigureAfter(DispatcherServletAutoConfiguration.class)
|
||||
@ -313,7 +313,7 @@ public class WebMvcAutoConfiguration {
|
||||
public ResourceHttpRequestHandler faviconRequestHandler() {
|
||||
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
|
||||
requestHandler
|
||||
.setLocations(this.resourceProperties.getFaviconLocations());
|
||||
.setLocations(this.resourceProperties.getFaviconLocations());
|
||||
return requestHandler;
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,8 @@ public class MessageSourceAutoConfigurationTests {
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +72,8 @@ public class MessageSourceAutoConfigurationTests {
|
||||
@Test
|
||||
public void testMultipleMessageSourceCreated() throws Exception {
|
||||
load("spring.messages.basename:test/messages,test/messages2");
|
||||
assertEquals("bar", this.context.getMessage("foo", null, "Foo message", Locale.UK));
|
||||
assertEquals("bar",
|
||||
this.context.getMessage("foo", null, "Foo message", Locale.UK));
|
||||
assertEquals("bar-bar",
|
||||
this.context.getMessage("foo-foo", null, "Foo-Foo message", Locale.UK));
|
||||
}
|
||||
@ -124,4 +125,5 @@ public class MessageSourceAutoConfigurationTests {
|
||||
protected static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -216,17 +216,17 @@ public class BatchAutoConfigurationTests {
|
||||
public void testRenamePrefix() throws Exception {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"spring.datasource.name:batchtest",
|
||||
"spring.batch.schema:classpath:batch/custom-schema-hsql.sql",
|
||||
"spring.batch.tablePrefix:PREFIX_");
|
||||
"spring.datasource.name:batchtest",
|
||||
"spring.batch.schema:classpath:batch/custom-schema-hsql.sql",
|
||||
"spring.batch.tablePrefix:PREFIX_");
|
||||
this.context.register(TestConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class,
|
||||
HibernateJpaAutoConfiguration.class, BatchAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
EmbeddedDataSourceConfiguration.class,
|
||||
HibernateJpaAutoConfiguration.class, BatchAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertNotNull(this.context.getBean(JobLauncher.class));
|
||||
assertEquals(0, new JdbcTemplate(this.context.getBean(DataSource.class))
|
||||
.queryForList("select * from PREFIX_JOB_EXECUTION").size());
|
||||
.queryForList("select * from PREFIX_JOB_EXECUTION").size());
|
||||
JobExplorer jobExplorer = this.context.getBean(JobExplorer.class);
|
||||
assertEquals(0, jobExplorer.findRunningJobExecutions("test").size());
|
||||
JobRepository jobRepository = this.context.getBean(JobRepository.class);
|
||||
|
@ -164,7 +164,9 @@ public class JobLauncherCommandLineRunnerTests {
|
||||
protected static class BatchConfiguration implements BatchConfigurer {
|
||||
|
||||
private ResourcelessTransactionManager transactionManager = new ResourcelessTransactionManager();
|
||||
|
||||
private JobRepository jobRepository;
|
||||
|
||||
private MapJobRepositoryFactoryBean jobRepositoryFactory = new MapJobRepositoryFactoryBean(
|
||||
this.transactionManager);
|
||||
|
||||
@ -198,6 +200,7 @@ public class JobLauncherCommandLineRunnerTests {
|
||||
public JobExplorer getJobExplorer() throws Exception {
|
||||
return new MapJobExplorerFactoryBean(this.jobRepositoryFactory).getObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,14 +26,13 @@ import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.apache.commons.dbcp.BasicDataSource;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
@ -43,6 +42,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@ -158,8 +159,8 @@ public class DataSourceAutoConfigurationTests {
|
||||
public void explicitType() {
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"spring.datasource.driverClassName:org.hsqldb.jdbcDriver",
|
||||
"spring.datasource.url:jdbc:hsqldb:mem:testdb",
|
||||
"spring.datasource.type:" + HikariDataSource.class.getName());
|
||||
"spring.datasource.url:jdbc:hsqldb:mem:testdb", "spring.datasource.type:"
|
||||
+ HikariDataSource.class.getName());
|
||||
this.context.register(DataSourceAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
@ -271,7 +272,8 @@ public class DataSourceAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") // see testExplicitDriverClassClearsUserName
|
||||
@SuppressWarnings("unused")
|
||||
// see testExplicitDriverClassClearsUserName
|
||||
public static class DatabaseDriver implements Driver {
|
||||
|
||||
@Override
|
||||
|
@ -16,12 +16,6 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.security;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
@ -63,6 +57,12 @@ import org.springframework.security.web.FilterChainProxy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link SecurityAutoConfiguration}.
|
||||
*
|
||||
@ -105,7 +105,7 @@ public class SecurityAutoConfigurationTests {
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertEquals(
|
||||
FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER-100,
|
||||
FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 100,
|
||||
this.context.getBean("securityFilterChainRegistration",
|
||||
FilterRegistrationBean.class).getOrder());
|
||||
}
|
||||
@ -136,7 +136,7 @@ public class SecurityAutoConfigurationTests {
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertEquals(
|
||||
FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER-100,
|
||||
FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 100,
|
||||
this.context.getBean("securityFilterChainRegistration",
|
||||
FilterRegistrationBean.class).getOrder());
|
||||
}
|
||||
@ -355,16 +355,14 @@ public class SecurityAutoConfigurationTests {
|
||||
public void testSecurityEvaluationContextExtensionSupport() {
|
||||
this.context = new AnnotationConfigWebApplicationContext();
|
||||
this.context.setServletContext(new MockServletContext());
|
||||
|
||||
this.context.register(AuthenticationManagerCustomizer.class,
|
||||
SecurityAutoConfiguration.class, ServerPropertiesAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
assertNotNull(this.context.getBean(SecurityEvaluationContextExtension.class));
|
||||
}
|
||||
|
||||
private static final class AuthenticationListener implements
|
||||
ApplicationListener<AbstractAuthenticationEvent> {
|
||||
ApplicationListener<AbstractAuthenticationEvent> {
|
||||
|
||||
private ApplicationEvent event;
|
||||
|
||||
@ -410,7 +408,7 @@ public class SecurityAutoConfigurationTests {
|
||||
|
||||
@Configuration
|
||||
protected static class WorkaroundSecurityCustomizer extends
|
||||
WebSecurityConfigurerAdapter {
|
||||
WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private AuthenticationManagerBuilder builder;
|
||||
@ -435,7 +433,7 @@ public class SecurityAutoConfigurationTests {
|
||||
@Configuration
|
||||
@Order(-1)
|
||||
protected static class AuthenticationManagerCustomizer extends
|
||||
GlobalAuthenticationConfigurerAdapter {
|
||||
GlobalAuthenticationConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
public void init(AuthenticationManagerBuilder auth) throws Exception {
|
||||
@ -446,7 +444,7 @@ public class SecurityAutoConfigurationTests {
|
||||
|
||||
@Configuration
|
||||
protected static class UserDetailsSecurityCustomizer extends
|
||||
WebSecurityConfigurerAdapter {
|
||||
WebSecurityConfigurerAdapter {
|
||||
|
||||
private UserDetailsService userDetails;
|
||||
|
||||
|
@ -200,11 +200,13 @@ public class ThymeleafAutoConfigurationTests {
|
||||
this.context.register(ThymeleafAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertEquals(0, this.context.getBeansOfType(ResourceUrlEncodingFilter.class).size());
|
||||
assertEquals(0, this.context.getBeansOfType(ResourceUrlEncodingFilter.class)
|
||||
.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerResourceHandlingFilterOnlyIfResourceChainIsEnabled() throws Exception {
|
||||
public void registerResourceHandlingFilterOnlyIfResourceChainIsEnabled()
|
||||
throws Exception {
|
||||
this.context.register(ThymeleafAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
|
@ -193,11 +193,13 @@ public class VelocityAutoConfigurationTests {
|
||||
@Test
|
||||
public void registerResourceHandlingFilterDisabledByDefault() throws Exception {
|
||||
registerAndRefreshContext();
|
||||
assertEquals(0, this.context.getBeansOfType(ResourceUrlEncodingFilter.class).size());
|
||||
assertEquals(0, this.context.getBeansOfType(ResourceUrlEncodingFilter.class)
|
||||
.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerResourceHandlingFilterOnlyIfResourceChainIsEnabled() throws Exception {
|
||||
public void registerResourceHandlingFilterOnlyIfResourceChainIsEnabled()
|
||||
throws Exception {
|
||||
registerAndRefreshContext("spring.resources.chain.enabled:true");
|
||||
assertNotNull(this.context.getBean(ResourceUrlEncodingFilter.class));
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ package org.springframework.boot.autoconfigure.web;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -71,7 +70,6 @@ public class ConditionalOnEnabledResourceChainTests {
|
||||
assertTrue(this.context.containsBean("foo"));
|
||||
}
|
||||
|
||||
|
||||
private void load(String... environment) {
|
||||
this.context.register(Config.class);
|
||||
EnvironmentTestUtils.addEnvironment(this.context, environment);
|
||||
|
@ -184,7 +184,7 @@ class ProjectGenerationRequest {
|
||||
* @return the package name or {@code null}
|
||||
*/
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
return this.packageName;
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
|
@ -266,9 +266,9 @@ public class InitCommandTests extends AbstractHttpClientMockTests {
|
||||
public void parseProjectOptions() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("-g=org.demo", "-a=acme", "-v=1.2.3-SNAPSHOT", "-n=acme-sample",
|
||||
"--description=Acme sample project", "--package-name=demo.foo", "-t=ant-project",
|
||||
"--build=grunt", "--format=web", "-p=war", "-j=1.9", "-l=groovy",
|
||||
"-b=1.2.0.RELEASE", "-d=web,data-jpa");
|
||||
"--description=Acme sample project", "--package-name=demo.foo",
|
||||
"-t=ant-project", "--build=grunt", "--format=web", "-p=war", "-j=1.9",
|
||||
"-l=groovy", "-b=1.2.0.RELEASE", "-d=web,data-jpa");
|
||||
assertEquals("org.demo", this.handler.lastRequest.getGroupId());
|
||||
assertEquals("acme", this.handler.lastRequest.getArtifactId());
|
||||
assertEquals("1.2.3-SNAPSHOT", this.handler.lastRequest.getVersion());
|
||||
|
@ -142,24 +142,21 @@ public class ProjectGenerationRequestTests {
|
||||
@Test
|
||||
public void outputCustomizeArtifactId() {
|
||||
this.request.setOutput("my-project");
|
||||
assertEquals(
|
||||
createDefaultUrl("?artifactId=my-project&type=test-type"),
|
||||
assertEquals(createDefaultUrl("?artifactId=my-project&type=test-type"),
|
||||
this.request.generateUrl(createDefaultMetadata()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputArchiveCustomizeArtifactId() {
|
||||
this.request.setOutput("my-project.zip");
|
||||
assertEquals(
|
||||
createDefaultUrl("?artifactId=my-project&type=test-type"),
|
||||
assertEquals(createDefaultUrl("?artifactId=my-project&type=test-type"),
|
||||
this.request.generateUrl(createDefaultMetadata()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputArchiveWithDotsCustomizeArtifactId() {
|
||||
this.request.setOutput("my.nice.project.zip");
|
||||
assertEquals(
|
||||
createDefaultUrl("?artifactId=my.nice.project&type=test-type"),
|
||||
assertEquals(createDefaultUrl("?artifactId=my.nice.project&type=test-type"),
|
||||
this.request.generateUrl(createDefaultMetadata()));
|
||||
}
|
||||
|
||||
@ -167,8 +164,7 @@ public class ProjectGenerationRequestTests {
|
||||
public void outputDoesNotOverrideCustomArtifactId() {
|
||||
this.request.setOutput("my-project");
|
||||
this.request.setArtifactId("my-id");
|
||||
assertEquals(
|
||||
createDefaultUrl("?artifactId=my-id&type=test-type"),
|
||||
assertEquals(createDefaultUrl("?artifactId=my-id&type=test-type"),
|
||||
this.request.generateUrl(createDefaultMetadata()));
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,6 @@ public class DevToolsProperties {
|
||||
|
||||
private static final long DEFAULT_RESTART_QUIET_PERIOD = 400;
|
||||
|
||||
|
||||
/**
|
||||
* Enable automatic restart.
|
||||
*/
|
||||
@ -117,7 +116,8 @@ public class DevToolsProperties {
|
||||
allExclude.addAll(StringUtils.commaDelimitedListToSet(this.exclude));
|
||||
}
|
||||
if (StringUtils.hasText(this.additionalExclude)) {
|
||||
allExclude.addAll(StringUtils.commaDelimitedListToSet(this.additionalExclude));
|
||||
allExclude.addAll(StringUtils
|
||||
.commaDelimitedListToSet(this.additionalExclude));
|
||||
}
|
||||
return allExclude.toArray(new String[allExclude.size()]);
|
||||
}
|
||||
|
@ -34,9 +34,11 @@ public class DevToolsPropertiesTests {
|
||||
public void additionalExcludeKeepsDefaults() {
|
||||
DevToolsProperties.Restart restart = this.devToolsProperties.getRestart();
|
||||
restart.setAdditionalExclude("foo/**,bar/**");
|
||||
assertThat(restart.getAllExclude(), arrayContaining("META-INF/maven/**",
|
||||
"META-INF/resources/**", "resources/**", "static/**", "public/**",
|
||||
"templates/**", "foo/**", "bar/**"));
|
||||
assertThat(
|
||||
restart.getAllExclude(),
|
||||
arrayContaining("META-INF/maven/**", "META-INF/resources/**",
|
||||
"resources/**", "static/**", "public/**", "templates/**",
|
||||
"foo/**", "bar/**"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -255,4 +255,5 @@ public class LocalDevToolsAutoConfigurationTests {
|
||||
public static class WebResourcesConfig {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -590,7 +590,8 @@ NOTE: The double backslashes are only required when you're using a properties fi
|
||||
configuration. If you are using YAML, single backslashes are sufficient and a value
|
||||
that's equivalent to the one shown above would be `192\.168\.\d{1,3}\.\d{1,3}`.
|
||||
|
||||
NOTE: You can trust all proxies by setting the `internal_proxies` to empty (but don't do this in production).
|
||||
NOTE: You can trust all proxies by setting the `internal_proxies` to empty (but don't do
|
||||
this in production).
|
||||
|
||||
You can take complete control of the configuration of the
|
||||
`RemoteIpValve` by switching the automatic one off (i.e. set one of
|
||||
@ -1164,16 +1165,17 @@ Check out {sc-spring-boot-autoconfigure}/web/WebMvcAutoConfiguration.{sc-ext}[`W
|
||||
{sc-spring-boot-autoconfigure}/velocity/VelocityAutoConfiguration.{sc-ext}[`VelocityAutoConfiguration`]
|
||||
|
||||
|
||||
|
||||
[[howto-customize-view-resolvers-velocity]]
|
||||
=== Velocity
|
||||
|
||||
By default, Spring Boot configures a `VelocityViewResolver`. If you need a `VelocityLayoutViewResolver`
|
||||
instead, you can easily configure your own by creating a bean with name `velocityViewResolver`. You can
|
||||
also inject the `VelocityProperties` instance to apply the base defaults to your custom view resolver.
|
||||
By default, Spring Boot configures a `VelocityViewResolver`. If you need a
|
||||
`VelocityLayoutViewResolver` instead, you can easily configure your own by creating a bean
|
||||
with name `velocityViewResolver`. You can also inject the `VelocityProperties` instance to
|
||||
apply the base defaults to your custom view resolver.
|
||||
|
||||
The following example replaces the auto-configured velocity view resolver with a
|
||||
`VelocityLayoutViewResolver` defining a customized `layoutUrl` and all settings that would have been
|
||||
applied from the auto-configuration:
|
||||
`VelocityLayoutViewResolver` defining a customized `layoutUrl` and all settings that would
|
||||
have been applied from the auto-configuration:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
@ -1187,6 +1189,7 @@ applied from the auto-configuration:
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[howto-logging]]
|
||||
== Logging
|
||||
|
||||
@ -1456,7 +1459,6 @@ entity manager based on the presence of a bean of that type.
|
||||
|
||||
[[howto-use-two-entity-managers]]
|
||||
=== Use Two EntityManagers
|
||||
|
||||
Even if the default `EntityManagerFactory` works fine, you will need to define a new one
|
||||
because otherwise the presence of the second bean of that type will switch off the
|
||||
default. To make it easy to do that you can use the convenient `EntityManagerBuilder`
|
||||
@ -1488,7 +1490,6 @@ Example:
|
||||
.persistenceUnit("orders")
|
||||
.build();
|
||||
}
|
||||
|
||||
----
|
||||
|
||||
The configuration above almost works on its own. To complete the picture you need to
|
||||
@ -1501,7 +1502,6 @@ If you are using Spring Data, you need to configure `@EnableJpaRepositories` acc
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
|
||||
@Configuration
|
||||
@EnableJpaRepositories(basePackageClasses = Customer.class,
|
||||
entityManagerFactoryRef = "customerEntityManagerFactory")
|
||||
@ -1515,11 +1515,10 @@ If you are using Spring Data, you need to configure `@EnableJpaRepositories` acc
|
||||
public class OrderConfiguration {
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[howto-use-traditional-persistence-xml]]
|
||||
=== Use a traditional persistence.xml
|
||||
Spring doesn't require the use of XML to configure the JPA provider, and Spring Boot
|
||||
|
@ -1351,9 +1351,10 @@ https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resou
|
||||
and in Spring Framework's {spring-reference}/#mvc-config-static-resources[reference documentation].
|
||||
====
|
||||
|
||||
|
||||
|
||||
[[boot-features-spring-mvc-web-binding-initializer]]
|
||||
==== ConfigurableWebBindingInitializer
|
||||
|
||||
Spring MVC uses a `WebBindingInitializer` to initialize a `WebDataBinder` for a particular
|
||||
request. If you create your own `ConfigurableWebBindingInitializer` `@Bean`, Spring Boot
|
||||
will automatically configure Spring MVC to use it.
|
||||
@ -3419,7 +3420,8 @@ You could also specify the `hazelcast.xml` configuration file to use via configu
|
||||
Otherwise, Spring Boot tries to find the Hazelcast configuration from the default
|
||||
locations, that is `hazelcast.xml` in the working directory or at the root of the
|
||||
classpath. We also check if the `hazelcast.config` system property is set. Check the
|
||||
http://docs.hazelcast.org/docs/latest/manual/html-single/[Hazelcast documentation] for more details.
|
||||
http://docs.hazelcast.org/docs/latest/manual/html-single/[Hazelcast documentation] for
|
||||
more details.
|
||||
|
||||
NOTE: Spring Boot also has an
|
||||
<<boot-features-caching-provider-hazelcast,explicit caching support for Hazelcast>>. The
|
||||
@ -3712,6 +3714,7 @@ TIP: A https://github.com/snicoll-demos/spring-boot-master-auto-configuration[de
|
||||
is available to showcase how you can create a starter step by step.
|
||||
|
||||
|
||||
|
||||
[[boot-features-understanding-auto-configured-beans]]
|
||||
=== Understanding auto-configured beans
|
||||
Under the hood, auto-configuration is implemented with standard `@Configuration` classes.
|
||||
@ -3818,9 +3821,9 @@ The `@ConditionalOnExpression` annotation allows configuration to be included ba
|
||||
result of a {spring-reference}/#expressions[SpEL expression].
|
||||
|
||||
|
||||
|
||||
[[boot-features-custom-starter]]
|
||||
=== Creating your own starter
|
||||
|
||||
A full Spring Boot starter for a library may contain the following components:
|
||||
|
||||
* The `autoconfigure` module that contains the auto-configuration code.
|
||||
@ -3831,10 +3834,11 @@ A full Spring Boot starter for a library may contain the following components:
|
||||
TIP: You may combine the auto-configuration code and the dependency management in a single
|
||||
module if you don't need to separate those two concerns.
|
||||
|
||||
|
||||
|
||||
[[boot-features-custom-starter-naming]]
|
||||
==== Naming
|
||||
|
||||
Please make sure to provide a proper namespace for your starter. Do not start your module
|
||||
FPlease make sure to provide a proper namespace for your starter. Do not start your module
|
||||
names with `spring-boot`, even if you are using a different Maven groupId. We may offer an
|
||||
official support for the thing you're auto-configuring in the future.
|
||||
|
||||
@ -3854,9 +3858,10 @@ meta-data generation>> so that IDE assistance is available for your keys as well
|
||||
may want to review the generated meta-data (`META-INF/spring-configuration-metadata.json`)
|
||||
to make sure your keys are properly documented.
|
||||
|
||||
|
||||
|
||||
[[boot-features-custom-starter-module-autoconfigure]]
|
||||
==== Autoconfigure module
|
||||
|
||||
The autoconfigure module contains everything that is necessary to get started with the
|
||||
library. It may also contain configuration keys definition (`@ConfigurationProperties`)
|
||||
and any callback interface that can be used to further customize how the components are
|
||||
@ -3866,9 +3871,10 @@ TIP: You should mark the dependencies to the library as optional so that you can
|
||||
the autoconfigure module in your projects more easily. If you do it that way, the library
|
||||
won't be provided and boot will backoff by default.
|
||||
|
||||
|
||||
|
||||
[[boot-features-custom-starter-module-starter]]
|
||||
==== Starter module
|
||||
|
||||
The starter is an empty jar, really. Its only purpose is to provide the necessary
|
||||
dependencies to work with the library; see it as an opinionated view of what is required
|
||||
to get started.
|
||||
@ -3879,6 +3885,8 @@ a proper set of _default_ dependencies may be hard if the number of optional dep
|
||||
is high as you should avoid bringing unnecessary dependencies for a typical usage of the
|
||||
library.
|
||||
|
||||
|
||||
|
||||
[[boot-features-websockets]]
|
||||
== WebSockets
|
||||
Spring Boot provides WebSockets auto-configuration for embedded Tomcat (8 and 7), Jetty 9
|
||||
|
@ -54,7 +54,6 @@ of the library that you want to use.
|
||||
|
||||
|
||||
|
||||
|
||||
=== EhCache 2.x
|
||||
Simply add the `net.sf.ehcache:ehcache` dependency to the project. Since there is a
|
||||
default `ehcache.xml` configuration file at the root of the classpath, it is automatically
|
||||
|
@ -41,7 +41,7 @@
|
||||
<artifactId>cache-api</artifactId>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
|
||||
<!-- Additional cache providers (uncomment to try them) -->
|
||||
<!--
|
||||
<dependency>
|
||||
|
@ -877,8 +877,8 @@ public class SpringApplication {
|
||||
public void setApplicationContextClass(
|
||||
Class<? extends ConfigurableApplicationContext> applicationContextClass) {
|
||||
this.applicationContextClass = applicationContextClass;
|
||||
if (!isSpringWebAvailable() || !WebApplicationContext.class.isAssignableFrom(
|
||||
applicationContextClass)) {
|
||||
if (!isSpringWebAvailable()
|
||||
|| !WebApplicationContext.class.isAssignableFrom(applicationContextClass)) {
|
||||
this.webEnvironment = false;
|
||||
}
|
||||
}
|
||||
|
@ -57,4 +57,12 @@ class OriginCapablePropertyValue extends PropertyValue {
|
||||
.getName() : "unknown";
|
||||
return "'" + name + "' from '" + source + "'";
|
||||
}
|
||||
|
||||
public static PropertyOrigin getOrigin(PropertyValue propertyValue) {
|
||||
if (propertyValue instanceof OriginCapablePropertyValue) {
|
||||
return ((OriginCapablePropertyValue) propertyValue).getOrigin();
|
||||
}
|
||||
return new OriginCapablePropertyValue(propertyValue).getOrigin();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ package org.springframework.boot.bind;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@ -35,6 +34,7 @@ import org.springframework.beans.InvalidPropertyException;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.NotWritablePropertyException;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
@ -52,15 +52,11 @@ import org.springframework.validation.DataBinder;
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @author Andy Wilkinson
|
||||
* @see RelaxedNames
|
||||
*/
|
||||
public class RelaxedDataBinder extends DataBinder {
|
||||
|
||||
private static final Set<String> BENIGN_PROPERTY_SOURCE_NAMES = Collections
|
||||
.unmodifiableSet(new HashSet<String>(Arrays.asList(
|
||||
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
|
||||
StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)));
|
||||
|
||||
private static final Object BLANK = new Object();
|
||||
|
||||
private String namePrefix;
|
||||
@ -83,12 +79,12 @@ public class RelaxedDataBinder extends DataBinder {
|
||||
* @param namePrefix An optional prefix to be used when reading properties
|
||||
*/
|
||||
public RelaxedDataBinder(Object target, String namePrefix) {
|
||||
super(wrapTarget(target),
|
||||
(StringUtils.hasLength(namePrefix) ? namePrefix : DEFAULT_OBJECT_NAME));
|
||||
super(wrapTarget(target), (StringUtils.hasLength(namePrefix) ? namePrefix
|
||||
: DEFAULT_OBJECT_NAME));
|
||||
this.namePrefix = cleanNamePrefix(namePrefix);
|
||||
}
|
||||
|
||||
private static String cleanNamePrefix(String namePrefix) {
|
||||
private String cleanNamePrefix(String namePrefix) {
|
||||
if (!StringUtils.hasLength(namePrefix)) {
|
||||
return null;
|
||||
}
|
||||
@ -146,8 +142,7 @@ public class RelaxedDataBinder extends DataBinder {
|
||||
propertyValues = addMapPrefix(propertyValues);
|
||||
}
|
||||
BeanWrapper wrapper = new BeanWrapperImpl(target);
|
||||
wrapper.setConversionService(
|
||||
new RelaxedConversionService(getConversionService()));
|
||||
wrapper.setConversionService(new RelaxedConversionService(getConversionService()));
|
||||
wrapper.setAutoGrowNestedPaths(true);
|
||||
List<PropertyValue> sortedValues = new ArrayList<PropertyValue>();
|
||||
Set<String> modifiedNames = new HashSet<String>();
|
||||
@ -214,9 +209,10 @@ public class RelaxedDataBinder extends DataBinder {
|
||||
if (name.startsWith(candidate)) {
|
||||
name = name.substring(candidate.length());
|
||||
if (!(this.ignoreNestedProperties && name.contains("."))) {
|
||||
PropertyOrigin propertyOrigin = findPropertyOrigin(value);
|
||||
rtn.addPropertyValue(new OriginCapablePropertyValue(name,
|
||||
value.getValue(), propertyOrigin));
|
||||
PropertyOrigin propertyOrigin = OriginCapablePropertyValue
|
||||
.getOrigin(value);
|
||||
rtn.addPropertyValue(new OriginCapablePropertyValue(name, value
|
||||
.getValue(), propertyOrigin));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -224,8 +220,7 @@ public class RelaxedDataBinder extends DataBinder {
|
||||
return rtn;
|
||||
}
|
||||
|
||||
private PropertyValue modifyProperty(BeanWrapper target,
|
||||
PropertyValue propertyValue) {
|
||||
private PropertyValue modifyProperty(BeanWrapper target, PropertyValue propertyValue) {
|
||||
String name = propertyValue.getName();
|
||||
String normalizedName = normalizePath(target, name);
|
||||
if (!normalizedName.equals(name)) {
|
||||
@ -251,55 +246,9 @@ public class RelaxedDataBinder extends DataBinder {
|
||||
|
||||
@Override
|
||||
protected AbstractPropertyBindingResult createBeanPropertyBindingResult() {
|
||||
return new BeanPropertyBindingResult(getTarget(), getObjectName(),
|
||||
isAutoGrowNestedPaths(), getAutoGrowCollectionLimit()) {
|
||||
@Override
|
||||
protected BeanWrapper createBeanWrapper() {
|
||||
BeanWrapper beanWrapper = new BeanWrapperImpl(getTarget()) {
|
||||
@Override
|
||||
public void setPropertyValue(PropertyValue pv) throws BeansException {
|
||||
try {
|
||||
super.setPropertyValue(pv);
|
||||
}
|
||||
catch (NotWritablePropertyException ex) {
|
||||
PropertyOrigin origin = findPropertyOrigin(pv);
|
||||
if (isFatal(origin)) {
|
||||
if (origin != null) {
|
||||
throw new RelaxedBindingNotWritablePropertyException(
|
||||
ex, origin);
|
||||
}
|
||||
else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.debug("Ignoring benign property binding failure",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
beanWrapper.setConversionService(
|
||||
new RelaxedConversionService(getConversionService()));
|
||||
beanWrapper.registerCustomEditor(InetAddress.class,
|
||||
new InetAddressEditor());
|
||||
return beanWrapper;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private boolean isFatal(PropertyOrigin origin) {
|
||||
if (origin == null) {
|
||||
return true;
|
||||
}
|
||||
return !BENIGN_PROPERTY_SOURCE_NAMES.contains(origin.getSource().getName());
|
||||
}
|
||||
|
||||
private PropertyOrigin findPropertyOrigin(PropertyValue propertyValue) {
|
||||
if (propertyValue instanceof OriginCapablePropertyValue) {
|
||||
return ((OriginCapablePropertyValue) propertyValue).getOrigin();
|
||||
}
|
||||
return new OriginCapablePropertyValue(propertyValue).getOrigin();
|
||||
return new RelaxedBeanPropertyBindingResult(getTarget(), getObjectName(),
|
||||
isAutoGrowNestedPaths(), getAutoGrowCollectionLimit(),
|
||||
getConversionService());
|
||||
}
|
||||
|
||||
private String initializePath(BeanWrapper wrapper, BeanPath path, int index) {
|
||||
@ -354,8 +303,8 @@ public class RelaxedDataBinder extends DataBinder {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private boolean isBlanked(BeanWrapper wrapper, String propertyName, String key) {
|
||||
Object value = (wrapper.isReadableProperty(propertyName)
|
||||
? wrapper.getPropertyValue(propertyName) : null);
|
||||
Object value = (wrapper.isReadableProperty(propertyName) ? wrapper
|
||||
.getPropertyValue(propertyName) : null);
|
||||
if (value instanceof Map) {
|
||||
if (((Map) value).get(key) == BLANK) {
|
||||
return true;
|
||||
@ -364,8 +313,7 @@ public class RelaxedDataBinder extends DataBinder {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void extendCollectionIfNecessary(BeanWrapper wrapper, BeanPath path,
|
||||
int index) {
|
||||
private void extendCollectionIfNecessary(BeanWrapper wrapper, BeanPath path, int index) {
|
||||
String name = path.prefix(index);
|
||||
TypeDescriptor elementDescriptor = wrapper.getPropertyTypeDescriptor(name)
|
||||
.getElementTypeDescriptor();
|
||||
@ -429,9 +377,8 @@ public class RelaxedDataBinder extends DataBinder {
|
||||
String nested = resolvePropertyName(target, prefix, candidate.toString());
|
||||
if (nested != null) {
|
||||
Class<?> type = target.getPropertyType(nested);
|
||||
if (type != null && Map.class.isAssignableFrom(type)) {
|
||||
// Special case for map property (gh-3836). Maybe could be fixed
|
||||
// in spring-beans)?
|
||||
if ((type != null) && Map.class.isAssignableFrom(type)) {
|
||||
// Special case for map property (gh-3836).
|
||||
return nested + "[" + name.substring(candidate.length() + 1) + "]";
|
||||
}
|
||||
String propertyName = resolvePropertyName(target,
|
||||
@ -507,6 +454,9 @@ public class RelaxedDataBinder extends DataBinder {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A path though properties of a bean.
|
||||
*/
|
||||
private static class BeanPath {
|
||||
|
||||
private List<PathNode> nodes;
|
||||
@ -678,4 +628,71 @@ public class RelaxedDataBinder extends DataBinder {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Extended version of {@link BeanPropertyBindingResult} to support relaxed binding.
|
||||
*/
|
||||
private static class RelaxedBeanPropertyBindingResult extends
|
||||
BeanPropertyBindingResult {
|
||||
|
||||
private RelaxedConversionService conversionService;
|
||||
|
||||
public RelaxedBeanPropertyBindingResult(Object target, String objectName,
|
||||
boolean autoGrowNestedPaths, int autoGrowCollectionLimit,
|
||||
ConversionService conversionService) {
|
||||
super(target, objectName, autoGrowNestedPaths, autoGrowCollectionLimit);
|
||||
this.conversionService = new RelaxedConversionService(conversionService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BeanWrapper createBeanWrapper() {
|
||||
BeanWrapper beanWrapper = new RelaxedBeanWrapper(getTarget());
|
||||
beanWrapper.setConversionService(this.conversionService);
|
||||
beanWrapper.registerCustomEditor(InetAddress.class, new InetAddressEditor());
|
||||
return beanWrapper;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Extended version of {@link BeanWrapperImpl} to support relaxed binding.
|
||||
*/
|
||||
private static class RelaxedBeanWrapper extends BeanWrapperImpl {
|
||||
|
||||
private static final Set<String> BENIGN_PROPERTY_SOURCE_NAMES;
|
||||
static {
|
||||
Set<String> names = new HashSet<String>();
|
||||
names.add(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
|
||||
names.add(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME);
|
||||
BENIGN_PROPERTY_SOURCE_NAMES = Collections.unmodifiableSet(names);
|
||||
}
|
||||
|
||||
public RelaxedBeanWrapper(Object target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyValue(PropertyValue pv) throws BeansException {
|
||||
try {
|
||||
super.setPropertyValue(pv);
|
||||
}
|
||||
catch (NotWritablePropertyException ex) {
|
||||
PropertyOrigin origin = OriginCapablePropertyValue.getOrigin(pv);
|
||||
if (isBenign(origin)) {
|
||||
logger.debug("Ignoring benign property binding failure", ex);
|
||||
return;
|
||||
}
|
||||
if (origin == null) {
|
||||
throw ex;
|
||||
}
|
||||
throw new RelaxedBindingNotWritablePropertyException(ex, origin);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBenign(PropertyOrigin origin) {
|
||||
String name = (origin == null ? null : origin.getSource().getName());
|
||||
return BENIGN_PROPERTY_SOURCE_NAMES.contains(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ import org.springframework.util.Assert;
|
||||
public class FilterRegistrationBean extends RegistrationBean {
|
||||
|
||||
/**
|
||||
* Filters that wrap the servlet request should have an order less than or equal to this.
|
||||
* Filters that wrap the servlet request should be ordered less than or equal to this.
|
||||
*/
|
||||
public static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = 0;
|
||||
|
||||
@ -296,7 +296,7 @@ public class FilterRegistrationBean extends RegistrationBean {
|
||||
else {
|
||||
if (servletNames.size() > 0) {
|
||||
logger.info("Mapping filter: '" + registration.getName()
|
||||
+ "' to servlets: " + servletNames);
|
||||
+ "' to servlets: " + servletNames);
|
||||
registration.addMappingForServletNames(dispatcherTypes, this.matchAfter,
|
||||
servletNames.toArray(new String[servletNames.size()]));
|
||||
}
|
||||
|
@ -35,4 +35,5 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface ConfigurationPropertiesBinding {
|
||||
|
||||
}
|
||||
|
@ -72,13 +72,13 @@ import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProcessor,
|
||||
BeanFactoryAware, ResourceLoaderAware, EnvironmentAware, ApplicationContextAware,
|
||||
InitializingBean, DisposableBean, PriorityOrdered {
|
||||
BeanFactoryAware, ResourceLoaderAware, EnvironmentAware, ApplicationContextAware,
|
||||
InitializingBean, DisposableBean, PriorityOrdered {
|
||||
|
||||
public static final String VALIDATOR_BEAN_NAME = "configurationPropertiesValidator";
|
||||
|
||||
private static final String[] VALIDATOR_CLASSES = { "javax.validation.Validator",
|
||||
"javax.validation.ValidatorFactory" };
|
||||
"javax.validation.ValidatorFactory" };
|
||||
|
||||
private ConfigurationBeanFactoryMetaData beans = new ConfigurationBeanFactoryMetaData();
|
||||
|
||||
@ -105,8 +105,8 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
private int order = Ordered.HIGHEST_PRECEDENCE + 1;
|
||||
|
||||
/**
|
||||
* A list of custom converters (in addition to the defaults) to use when
|
||||
* converting properties for binding.
|
||||
* A list of custom converters (in addition to the defaults) to use when converting
|
||||
* properties for binding.
|
||||
* @param converters the converters to set
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
@ -262,8 +262,8 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
ConfigurationProperties annotation = AnnotationUtils
|
||||
.findAnnotation(bean.getClass(), ConfigurationProperties.class);
|
||||
ConfigurationProperties annotation = AnnotationUtils.findAnnotation(
|
||||
bean.getClass(), ConfigurationProperties.class);
|
||||
if (annotation != null || bean instanceof ConfigurationPropertiesHolder) {
|
||||
postProcessBeforeInitialization(bean, beanName, annotation);
|
||||
}
|
||||
@ -283,13 +283,13 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
|
||||
private void postProcessBeforeInitialization(Object bean, String beanName,
|
||||
ConfigurationProperties annotation) {
|
||||
Object target = (bean instanceof ConfigurationPropertiesHolder
|
||||
? ((ConfigurationPropertiesHolder) bean).getTarget() : bean);
|
||||
Object target = (bean instanceof ConfigurationPropertiesHolder ? ((ConfigurationPropertiesHolder) bean)
|
||||
.getTarget() : bean);
|
||||
PropertiesConfigurationFactory<Object> factory = new PropertiesConfigurationFactory<Object>(
|
||||
target);
|
||||
if (annotation != null && annotation.locations().length != 0) {
|
||||
factory.setPropertySources(
|
||||
loadPropertySources(annotation.locations(), annotation.merge()));
|
||||
factory.setPropertySources(loadPropertySources(annotation.locations(),
|
||||
annotation.merge()));
|
||||
}
|
||||
else {
|
||||
factory.setPropertySources(this.propertySources);
|
||||
@ -297,15 +297,15 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
factory.setValidator(determineValidator(bean));
|
||||
// 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);
|
||||
factory.setConversionService(this.conversionService == null ? getDefaultConversionService()
|
||||
: this.conversionService);
|
||||
if (annotation != null) {
|
||||
factory.setIgnoreInvalidFields(annotation.ignoreInvalidFields());
|
||||
factory.setIgnoreUnknownFields(annotation.ignoreUnknownFields());
|
||||
factory.setExceptionIfInvalid(annotation.exceptionIfInvalid());
|
||||
factory.setIgnoreNestedProperties(annotation.ignoreNestedProperties());
|
||||
String targetName = (StringUtils.hasLength(annotation.value())
|
||||
? annotation.value() : annotation.prefix());
|
||||
String targetName = (StringUtils.hasLength(annotation.value()) ? annotation
|
||||
.value() : annotation.prefix());
|
||||
if (StringUtils.hasLength(targetName)) {
|
||||
factory.setTargetName(targetName);
|
||||
}
|
||||
@ -316,8 +316,7 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
catch (Exception ex) {
|
||||
String targetClass = ClassUtils.getShortName(target.getClass());
|
||||
throw new BeanCreationException(beanName, "Could not bind properties to "
|
||||
+ targetClass + " (" + getAnnotationDetails(annotation) + ")",
|
||||
ex);
|
||||
+ targetClass + " (" + getAnnotationDetails(annotation) + ")", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,18 +325,19 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
return "";
|
||||
}
|
||||
StringBuilder details = new StringBuilder();
|
||||
details.append("prefix=").append((StringUtils.hasLength(annotation.value())
|
||||
? annotation.value() : annotation.prefix()));
|
||||
details.append("prefix=").append(
|
||||
(StringUtils.hasLength(annotation.value()) ? annotation.value()
|
||||
: annotation.prefix()));
|
||||
details.append(", ignoreInvalidFields=").append(annotation.ignoreInvalidFields());
|
||||
details.append(", ignoreUnknownFields=").append(annotation.ignoreUnknownFields());
|
||||
details.append(", ignoreNestedProperties=")
|
||||
.append(annotation.ignoreNestedProperties());
|
||||
details.append(", ignoreNestedProperties=").append(
|
||||
annotation.ignoreNestedProperties());
|
||||
return details.toString();
|
||||
}
|
||||
|
||||
private Validator determineValidator(Object bean) {
|
||||
boolean globalValidatorSupportBean = (this.validator != null
|
||||
&& this.validator.supports(bean.getClass()));
|
||||
boolean globalValidatorSupportBean = (this.validator != null && this.validator
|
||||
.supports(bean.getClass()));
|
||||
if (ClassUtils.isAssignable(Validator.class, bean.getClass())) {
|
||||
if (!globalValidatorSupportBean) {
|
||||
return (Validator) bean;
|
||||
@ -352,8 +352,8 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
try {
|
||||
PropertySourcesLoader loader = new PropertySourcesLoader();
|
||||
for (String location : locations) {
|
||||
Resource resource = this.resourceLoader
|
||||
.getResource(this.environment.resolvePlaceholders(location));
|
||||
Resource resource = this.resourceLoader.getResource(this.environment
|
||||
.resolvePlaceholders(location));
|
||||
String[] profiles = this.environment.getActiveProfiles();
|
||||
for (int i = profiles.length; i-- > 0;) {
|
||||
String profile = profiles[i];
|
||||
@ -377,8 +377,7 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
private ConversionService getDefaultConversionService() {
|
||||
if (this.defaultConversionService == null) {
|
||||
DefaultConversionService conversionService = new DefaultConversionService();
|
||||
this.applicationContext.getAutowireCapableBeanFactory()
|
||||
.autowireBean(this);
|
||||
this.applicationContext.getAutowireCapableBeanFactory().autowireBean(this);
|
||||
for (Converter<?, ?> converter : this.converters) {
|
||||
conversionService.addConverter(converter);
|
||||
}
|
||||
@ -388,8 +387,8 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory to create JSR 303 LocalValidatorFactoryBean. Inner class to prevent
|
||||
* class loader issues.
|
||||
* Factory to create JSR 303 LocalValidatorFactoryBean. Inner class to prevent class
|
||||
* loader issues.
|
||||
*/
|
||||
private static class Jsr303ValidatorFactory {
|
||||
|
||||
@ -403,8 +402,8 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Validator} implementation that wraps {@link Validator} instances and
|
||||
* chains their execution.
|
||||
* {@link Validator} implementation that wraps {@link Validator} instances and chains
|
||||
* their execution.
|
||||
*/
|
||||
private static class ChainingValidator implements Validator {
|
||||
|
||||
@ -438,8 +437,7 @@ InitializingBean, DisposableBean, PriorityOrdered {
|
||||
|
||||
/**
|
||||
* Convenience class to flatten out a tree of property sources without losing the
|
||||
* reference to the backing data (which can therefore be updated in the
|
||||
* background).
|
||||
* reference to the backing data (which can therefore be updated in the background).
|
||||
*/
|
||||
private static class FlatPropertySources implements PropertySources {
|
||||
|
||||
|
@ -26,8 +26,8 @@ import org.springframework.web.filter.CharacterEncodingFilter;
|
||||
* @author Phillip Webb
|
||||
* @since 1.2.1
|
||||
*/
|
||||
public class OrderedCharacterEncodingFilter extends CharacterEncodingFilter
|
||||
implements Ordered {
|
||||
public class OrderedCharacterEncodingFilter extends CharacterEncodingFilter implements
|
||||
Ordered {
|
||||
|
||||
private int order = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 9800;
|
||||
|
||||
|
@ -27,7 +27,7 @@ import org.springframework.web.filter.HiddenHttpMethodFilter;
|
||||
* @since 1.2.4
|
||||
*/
|
||||
public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter implements
|
||||
Ordered {
|
||||
Ordered {
|
||||
|
||||
/**
|
||||
* The default order is high to ensure the filter is applied before Spring Security.
|
||||
|
@ -27,7 +27,7 @@ import org.springframework.web.filter.HttpPutFormContentFilter;
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public class OrderedHttpPutFormContentFilter extends HttpPutFormContentFilter implements
|
||||
Ordered {
|
||||
Ordered {
|
||||
|
||||
/**
|
||||
* Higher order to ensure the filter is applied before Spring Security.
|
||||
|
@ -31,7 +31,6 @@ public interface EnvironmentPostProcessor {
|
||||
|
||||
/**
|
||||
* Post-process the given {@code environment}
|
||||
*
|
||||
* @param environment the environment to post-process
|
||||
* @param application the application to which the environment belongs
|
||||
*/
|
||||
|
@ -200,7 +200,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
||||
}
|
||||
|
||||
private String getExceptionConversionWord(ConfigurableEnvironment environment) {
|
||||
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment, "logging.");
|
||||
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment,
|
||||
"logging.");
|
||||
return resolver.getProperty("exception-conversion-word", "%rEx");
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ import org.springframework.context.annotation.ScannedGenericBeanDefinition;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Abstract base class for handlers of Servlet components discovered via classpath
|
||||
@ -49,15 +50,14 @@ abstract class ServletComponentHandler {
|
||||
}
|
||||
|
||||
protected String[] extractUrlPatterns(String attribute, Map<String, Object> attributes) {
|
||||
String[] value = (String[]) attributes.get("value");
|
||||
String[] urlPatterns = (String[]) attributes.get("urlPatterns");
|
||||
if (urlPatterns.length > 0) {
|
||||
if (((String[]) attributes.get("value")).length > 0) {
|
||||
throw new IllegalStateException("The urlPatterns and value attributes "
|
||||
+ "are mututally exclusive");
|
||||
}
|
||||
Assert.state(value.length == 0, "The urlPatterns and value attributes "
|
||||
+ "are mututally exclusive");
|
||||
return urlPatterns;
|
||||
}
|
||||
return (String[]) attributes.get("value");
|
||||
return value;
|
||||
}
|
||||
|
||||
protected final Map<String, String> extractInitParameters(
|
||||
@ -84,4 +84,4 @@ abstract class ServletComponentHandler {
|
||||
protected abstract void doHandle(Map<String, Object> attributes,
|
||||
BeanDefinition beanDefinition, BeanDefinitionRegistry registry);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.boot.web.servlet;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -43,8 +43,14 @@ import org.springframework.context.annotation.ScannedGenericBeanDefinition;
|
||||
class ServletComponentRegisteringPostProcessor implements BeanFactoryPostProcessor,
|
||||
ApplicationContextAware {
|
||||
|
||||
private final List<ServletComponentHandler> handlers = Arrays.asList(
|
||||
new WebServletHandler(), new WebFilterHandler(), new WebListenerHandler());
|
||||
private static final List<ServletComponentHandler> HANDLERS;
|
||||
static {
|
||||
List<ServletComponentHandler> handers = new ArrayList<ServletComponentHandler>();
|
||||
handers.add(new WebServletHandler());
|
||||
handers.add(new WebFilterHandler());
|
||||
handers.add(new WebListenerHandler());
|
||||
HANDLERS = Collections.unmodifiableList(handers);
|
||||
}
|
||||
|
||||
private final Set<String> packagesToScan;
|
||||
|
||||
@ -60,14 +66,20 @@ class ServletComponentRegisteringPostProcessor implements BeanFactoryPostProcess
|
||||
if (isRunningInEmbeddedContainer()) {
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = createComponentProvider();
|
||||
for (String packageToScan : this.packagesToScan) {
|
||||
for (BeanDefinition candidate : componentProvider
|
||||
.findCandidateComponents(packageToScan)) {
|
||||
if (candidate instanceof ScannedGenericBeanDefinition) {
|
||||
for (ServletComponentHandler handler : this.handlers) {
|
||||
handler.handle(((ScannedGenericBeanDefinition) candidate),
|
||||
(BeanDefinitionRegistry) this.applicationContext);
|
||||
}
|
||||
}
|
||||
scanPackage(componentProvider, packageToScan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scanPackage(
|
||||
ClassPathScanningCandidateComponentProvider componentProvider,
|
||||
String packageToScan) {
|
||||
for (BeanDefinition candidate : componentProvider
|
||||
.findCandidateComponents(packageToScan)) {
|
||||
if (candidate instanceof ScannedGenericBeanDefinition) {
|
||||
for (ServletComponentHandler handler : HANDLERS) {
|
||||
handler.handle(((ScannedGenericBeanDefinition) candidate),
|
||||
(BeanDefinitionRegistry) this.applicationContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,7 +94,7 @@ class ServletComponentRegisteringPostProcessor implements BeanFactoryPostProcess
|
||||
private ClassPathScanningCandidateComponentProvider createComponentProvider() {
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
|
||||
false);
|
||||
for (ServletComponentHandler handler : this.handlers) {
|
||||
for (ServletComponentHandler handler : HANDLERS) {
|
||||
componentProvider.addIncludeFilter(handler.getTypeFilter());
|
||||
}
|
||||
return componentProvider;
|
||||
|
@ -53,7 +53,6 @@ public @interface ServletComponentScan {
|
||||
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
|
||||
* declarations e.g.: {@code @ServletComponentScan("org.my.pkg")} instead of
|
||||
* {@code @ServletComponentScan(basePackages="org.my.pkg")}.
|
||||
*
|
||||
* @return the base packages to scan
|
||||
*/
|
||||
String[] value() default {};
|
||||
@ -64,7 +63,6 @@ public @interface ServletComponentScan {
|
||||
* <p>
|
||||
* Use {@link #basePackageClasses()} for a type-safe alternative to String-based
|
||||
* package names.
|
||||
*
|
||||
* @return the base packages to scan
|
||||
*/
|
||||
String[] basePackages() default {};
|
||||
@ -73,8 +71,8 @@ public @interface ServletComponentScan {
|
||||
* Type-safe alternative to {@link #basePackages()} for specifying the packages to
|
||||
* scan for annotated servlet components. The package of each class specified will be
|
||||
* scanned.
|
||||
*
|
||||
* @return classes from the base packages to scan
|
||||
*/
|
||||
Class<?>[] basePackageClasses() default {};
|
||||
|
||||
}
|
||||
|
@ -53,16 +53,6 @@ class ServletComponentScanRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
}
|
||||
}
|
||||
|
||||
private void addPostProcessor(BeanDefinitionRegistry registry,
|
||||
Set<String> packagesToScan) {
|
||||
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
|
||||
beanDefinition.setBeanClass(ServletComponentRegisteringPostProcessor.class);
|
||||
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(
|
||||
packagesToScan);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
registry.registerBeanDefinition(BEAN_NAME, beanDefinition);
|
||||
}
|
||||
|
||||
private void updatePostProcessor(BeanDefinitionRegistry registry,
|
||||
Set<String> packagesToScan) {
|
||||
BeanDefinition definition = registry.getBeanDefinition(BEAN_NAME);
|
||||
@ -75,6 +65,16 @@ class ServletComponentScanRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
constructorArguments.setValue(packagesToScan);
|
||||
}
|
||||
|
||||
private void addPostProcessor(BeanDefinitionRegistry registry,
|
||||
Set<String> packagesToScan) {
|
||||
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
|
||||
beanDefinition.setBeanClass(ServletComponentRegisteringPostProcessor.class);
|
||||
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(
|
||||
packagesToScan);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
registry.registerBeanDefinition(BEAN_NAME, beanDefinition);
|
||||
}
|
||||
|
||||
private Set<String> getPackagesToScan(AnnotationMetadata metadata) {
|
||||
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata
|
||||
.getAnnotationAttributes(ServletComponentScan.class.getName()));
|
||||
|
@ -76,4 +76,4 @@ class WebFilterHandler extends ServletComponentHandler {
|
||||
.get("filterName") : beanDefinition.getBeanClassName());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -46,4 +46,4 @@ class WebListenerHandler extends ServletComponentHandler {
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -59,4 +59,4 @@ class WebServletHandler extends ServletComponentHandler {
|
||||
.get("name") : beanDefinition.getBeanClassName());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
* Copyright 2012-2015 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.
|
||||
@ -16,9 +16,6 @@
|
||||
|
||||
package org.springframework.boot.bind;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -35,6 +32,9 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConfigurationProperties} binding with custom converters.
|
||||
*
|
||||
@ -82,6 +82,7 @@ public class ConverterBindingTests {
|
||||
}
|
||||
|
||||
public static class Foo {
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
@ -96,6 +97,7 @@ public class ConverterBindingTests {
|
||||
|
||||
@ConfigurationProperties
|
||||
public static class Wrapper {
|
||||
|
||||
private Foo foo;
|
||||
|
||||
public Foo getFoo() {
|
||||
@ -105,6 +107,7 @@ public class ConverterBindingTests {
|
||||
public void setFoo(Foo foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,15 +16,6 @@
|
||||
|
||||
package org.springframework.boot.bind;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@ -60,6 +51,15 @@ import org.springframework.validation.DataBinder;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link RelaxedDataBinder}.
|
||||
*
|
||||
@ -710,7 +710,7 @@ public class RelaxedDataBinderTests {
|
||||
}
|
||||
|
||||
public static class RequiredKeysValidator implements
|
||||
ConstraintValidator<RequiredKeys, Map<String, Object>> {
|
||||
ConstraintValidator<RequiredKeys, Map<String, Object>> {
|
||||
|
||||
private String[] fields;
|
||||
|
||||
|
@ -97,7 +97,8 @@ public class ConfigurationPropertiesBindingPostProcessorTests {
|
||||
fail("Expected exception");
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
RelaxedBindingNotWritablePropertyException bex = (RelaxedBindingNotWritablePropertyException) ex.getRootCause();
|
||||
RelaxedBindingNotWritablePropertyException bex = (RelaxedBindingNotWritablePropertyException) ex
|
||||
.getRootCause();
|
||||
assertThat(bex.getMessage(),
|
||||
startsWith("Failed to bind 'com.example.baz' from 'test' to 'baz' "
|
||||
+ "property on '" + TestConfiguration.class.getName()));
|
||||
|
@ -65,6 +65,7 @@ public class ServletComponentScanIntegrationTests {
|
||||
public TomcatEmbeddedServletContainerFactory servletContainerFactory() {
|
||||
return new TomcatEmbeddedServletContainerFactory(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user