parent
711169aa8a
commit
8f693a0277
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2019 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
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.context.properties;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||||
|
import org.springframework.core.KotlinDetector;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a bean definition for a type annotated with {@link ConfigurationProperties}
|
||||||
|
* using the prefix of the annotation in the bean name.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
*/
|
||||||
|
final class ConfigurationPropertiesBeanDefinitionRegistrar {
|
||||||
|
|
||||||
|
private ConfigurationPropertiesBeanDefinitionRegistrar() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_PRESENT = KotlinDetector.isKotlinPresent();
|
||||||
|
|
||||||
|
public static void register(BeanDefinitionRegistry registry,
|
||||||
|
ConfigurableListableBeanFactory beanFactory, Class<?> type) {
|
||||||
|
String name = getName(type);
|
||||||
|
if (!containsBeanDefinition(beanFactory, name)) {
|
||||||
|
registerBeanDefinition(registry, beanFactory, name, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getName(Class<?> type) {
|
||||||
|
ConfigurationProperties annotation = AnnotationUtils.findAnnotation(type,
|
||||||
|
ConfigurationProperties.class);
|
||||||
|
String prefix = (annotation != null) ? annotation.prefix() : "";
|
||||||
|
return (StringUtils.hasText(prefix) ? prefix + "-" + type.getName()
|
||||||
|
: type.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean containsBeanDefinition(
|
||||||
|
ConfigurableListableBeanFactory beanFactory, String name) {
|
||||||
|
if (beanFactory.containsBeanDefinition(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
BeanFactory parent = beanFactory.getParentBeanFactory();
|
||||||
|
if (parent instanceof ConfigurableListableBeanFactory) {
|
||||||
|
return containsBeanDefinition((ConfigurableListableBeanFactory) parent, name);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void registerBeanDefinition(BeanDefinitionRegistry registry,
|
||||||
|
ConfigurableListableBeanFactory beanFactory, String name, Class<?> type) {
|
||||||
|
assertHasAnnotation(type);
|
||||||
|
registry.registerBeanDefinition(name,
|
||||||
|
createBeanDefinition(beanFactory, name, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertHasAnnotation(Class<?> type) {
|
||||||
|
Assert.notNull(
|
||||||
|
AnnotationUtils.findAnnotation(type, ConfigurationProperties.class),
|
||||||
|
() -> "No " + ConfigurationProperties.class.getSimpleName()
|
||||||
|
+ " annotation found on '" + type.getName() + "'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BeanDefinition createBeanDefinition(
|
||||||
|
ConfigurableListableBeanFactory beanFactory, String name, Class<?> type) {
|
||||||
|
if (canBindAtCreationTime(type)) {
|
||||||
|
return ConfigurationPropertiesBeanDefinition.from(beanFactory, name, type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GenericBeanDefinition definition = new GenericBeanDefinition();
|
||||||
|
definition.setBeanClass(type);
|
||||||
|
return definition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean canBindAtCreationTime(Class<?> type) {
|
||||||
|
List<Constructor<?>> constructors = determineConstructors(type);
|
||||||
|
return (constructors.size() == 1 && constructors.get(0).getParameterCount() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Constructor<?>> determineConstructors(Class<?> type) {
|
||||||
|
List<Constructor<?>> constructors = new ArrayList<>();
|
||||||
|
if (KOTLIN_PRESENT && KotlinDetector.isKotlinType(type)) {
|
||||||
|
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(type);
|
||||||
|
if (primaryConstructor != null) {
|
||||||
|
constructors.add(primaryConstructor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
constructors.addAll(Arrays.asList(type.getDeclaredConstructors()));
|
||||||
|
}
|
||||||
|
return constructors;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2019 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
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.context.properties;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.core.annotation.AliasFor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the base packages used when scanning for {@link ConfigurationProperties}
|
||||||
|
* classes. One of {@link #basePackageClasses()}, {@link #basePackages()} or its alias
|
||||||
|
* {@link #value()} may be specified to define specific packages to scan. If specific
|
||||||
|
* packages are not defined scanning will occur from the package of the class with this
|
||||||
|
* annotation.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
* @since 2.2.0
|
||||||
|
* @see ConfigurationPropertiesScanRegistrar
|
||||||
|
*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Import(ConfigurationPropertiesScanRegistrar.class)
|
||||||
|
public @interface ConfigurationPropertiesScan {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
|
||||||
|
* declarations e.g.: {@code @ConfigurationPropertiesScan("org.my.pkg")} instead of
|
||||||
|
* {@code @ConfigurationPropertiesScan(basePackages="org.my.pkg")}.
|
||||||
|
* @return the base packages to scan
|
||||||
|
*/
|
||||||
|
@AliasFor("basePackages")
|
||||||
|
String[] value() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base packages to scan for configuration properties. {@link #value()} is an alias
|
||||||
|
* for (and mutually exclusive with) this attribute.
|
||||||
|
* <p>
|
||||||
|
* Use {@link #basePackageClasses()} for a type-safe alternative to String-based
|
||||||
|
* package names.
|
||||||
|
* @return the base packages to scan
|
||||||
|
*/
|
||||||
|
@AliasFor("value")
|
||||||
|
String[] basePackages() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type-safe alternative to {@link #basePackages()} for specifying the packages to
|
||||||
|
* scan for configuration properties. 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 classes from the base packages to scan
|
||||||
|
*/
|
||||||
|
Class<?>[] basePackageClasses() default {};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2019 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
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.context.properties;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||||
|
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||||
|
import org.springframework.core.annotation.AnnotationAttributes;
|
||||||
|
import org.springframework.core.type.AnnotationMetadata;
|
||||||
|
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ImportBeanDefinitionRegistrar} for registering {@link ConfigurationProperties}
|
||||||
|
* bean definitions via scanning.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
*/
|
||||||
|
class ConfigurationPropertiesScanRegistrar implements ImportBeanDefinitionRegistrar {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
|
||||||
|
BeanDefinitionRegistry registry) {
|
||||||
|
Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);
|
||||||
|
register(registry, (ConfigurableListableBeanFactory) registry, packagesToScan);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getPackagesToScan(AnnotationMetadata metadata) {
|
||||||
|
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata
|
||||||
|
.getAnnotationAttributes(ConfigurationPropertiesScan.class.getName()));
|
||||||
|
String[] basePackages = attributes.getStringArray("basePackages");
|
||||||
|
Class<?>[] basePackageClasses = attributes.getClassArray("basePackageClasses");
|
||||||
|
Set<String> packagesToScan = new LinkedHashSet<>(Arrays.asList(basePackages));
|
||||||
|
for (Class<?> basePackageClass : basePackageClasses) {
|
||||||
|
packagesToScan.add(ClassUtils.getPackageName(basePackageClass));
|
||||||
|
}
|
||||||
|
if (packagesToScan.isEmpty()) {
|
||||||
|
packagesToScan.add(ClassUtils.getPackageName(metadata.getClassName()));
|
||||||
|
}
|
||||||
|
return packagesToScan;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void register(BeanDefinitionRegistry registry,
|
||||||
|
ConfigurableListableBeanFactory beanFactory, Set<String> packagesToScan) {
|
||||||
|
scan(packagesToScan, beanFactory, registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void scan(Set<String> packages, ConfigurableListableBeanFactory beanFactory,
|
||||||
|
BeanDefinitionRegistry registry) {
|
||||||
|
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(
|
||||||
|
false);
|
||||||
|
scanner.addIncludeFilter(new AnnotationTypeFilter(ConfigurationProperties.class));
|
||||||
|
for (String basePackage : packages) {
|
||||||
|
if (StringUtils.hasText(basePackage)) {
|
||||||
|
for (BeanDefinition candidate : scanner
|
||||||
|
.findCandidateComponents(basePackage)) {
|
||||||
|
String beanClassName = candidate.getBeanClassName();
|
||||||
|
try {
|
||||||
|
Class<?> type = ClassUtils.forName(beanClassName, null);
|
||||||
|
ConfigurationPropertiesBeanDefinitionRegistrar.register(registry,
|
||||||
|
beanFactory, type);
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException ex) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2019 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
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.context.properties;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||||
|
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||||
|
import org.springframework.boot.context.properties.scan.ConfigurationPropertiesScanConfiguration;
|
||||||
|
import org.springframework.core.type.AnnotationMetadata;
|
||||||
|
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link ConfigurationPropertiesScanRegistrar}.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
*/
|
||||||
|
public class ConfigurationPropertiesScanRegistrarTests {
|
||||||
|
|
||||||
|
private final ConfigurationPropertiesScanRegistrar registrar = new ConfigurationPropertiesScanRegistrar();
|
||||||
|
|
||||||
|
private final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registerBeanDefintionsShouldScanForConfigurationProperties()
|
||||||
|
throws IOException {
|
||||||
|
this.registrar.registerBeanDefinitions(
|
||||||
|
getAnnotationMetadata(ConfigurationPropertiesScanConfiguration.class),
|
||||||
|
this.beanFactory);
|
||||||
|
BeanDefinition bingDefinition = this.beanFactory.getBeanDefinition(
|
||||||
|
"bing-org.springframework.boot.context.properties.scan.ConfigurationPropertiesScanConfiguration$BingProperties");
|
||||||
|
BeanDefinition fooDefinition = this.beanFactory.getBeanDefinition(
|
||||||
|
"foo-org.springframework.boot.context.properties.scan.ConfigurationPropertiesScanConfiguration$FooProperties");
|
||||||
|
BeanDefinition barDefinition = this.beanFactory.getBeanDefinition(
|
||||||
|
"bar-org.springframework.boot.context.properties.scan.ConfigurationPropertiesScanConfiguration$BarProperties");
|
||||||
|
assertThat(bingDefinition).isExactlyInstanceOf(GenericBeanDefinition.class);
|
||||||
|
assertThat(fooDefinition).isExactlyInstanceOf(GenericBeanDefinition.class);
|
||||||
|
assertThat(barDefinition)
|
||||||
|
.isExactlyInstanceOf(ConfigurationPropertiesBeanDefinition.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void scanWhenBeanDefinitionExistsShouldSkip() throws IOException {
|
||||||
|
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||||
|
beanFactory.setAllowBeanDefinitionOverriding(false);
|
||||||
|
this.registrar.registerBeanDefinitions(
|
||||||
|
getAnnotationMetadata(
|
||||||
|
ConfigurationPropertiesScanConfiguration.TestConfiguration.class),
|
||||||
|
beanFactory);
|
||||||
|
BeanDefinition fooDefinition = beanFactory.getBeanDefinition(
|
||||||
|
"foo-org.springframework.boot.context.properties.scan.ConfigurationPropertiesScanConfiguration$FooProperties");
|
||||||
|
assertThat(fooDefinition).isExactlyInstanceOf(GenericBeanDefinition.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void scanWhenBasePackagesAndBasePackcageClassesProvidedShouldUseThat()
|
||||||
|
throws IOException {
|
||||||
|
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||||
|
beanFactory.setAllowBeanDefinitionOverriding(false);
|
||||||
|
this.registrar.registerBeanDefinitions(getAnnotationMetadata(
|
||||||
|
ConfigurationPropertiesScanConfiguration.DifferentPackageConfiguration.class),
|
||||||
|
beanFactory);
|
||||||
|
assertThat(beanFactory.containsBeanDefinition(
|
||||||
|
"foo-org.springframework.boot.context.properties.scan.ConfigurationPropertiesScanConfiguration$FooProperties"))
|
||||||
|
.isFalse();
|
||||||
|
BeanDefinition aDefinition = beanFactory.getBeanDefinition(
|
||||||
|
"a-org.springframework.boot.context.properties.scan.a.AScanConfiguration$AProperties");
|
||||||
|
BeanDefinition bDefinition = beanFactory.getBeanDefinition(
|
||||||
|
"b-org.springframework.boot.context.properties.scan.b.BScanConfiguration$BProperties");
|
||||||
|
assertThat(aDefinition).isExactlyInstanceOf(GenericBeanDefinition.class);
|
||||||
|
assertThat(bDefinition).isExactlyInstanceOf(GenericBeanDefinition.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AnnotationMetadata getAnnotationMetadata(Class<?> source) throws IOException {
|
||||||
|
return new SimpleMetadataReaderFactory().getMetadataReader(source.getName())
|
||||||
|
.getAnnotationMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2019 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
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.context.properties.scan;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.scan.b.BScanConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for testing {@link ConfigurationProperties} scanning.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
*/
|
||||||
|
@ConfigurationPropertiesScan
|
||||||
|
public class ConfigurationPropertiesScanConfiguration {
|
||||||
|
|
||||||
|
@ConfigurationPropertiesScan
|
||||||
|
@EnableConfigurationProperties({
|
||||||
|
ConfigurationPropertiesScanConfiguration.FooProperties.class })
|
||||||
|
public static class TestConfiguration {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigurationPropertiesScan(basePackages = "org.springframework.boot.context.properties.scan.a", basePackageClasses = BScanConfiguration.class)
|
||||||
|
public static class DifferentPackageConfiguration {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "foo")
|
||||||
|
static class FooProperties {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "bar")
|
||||||
|
public static class BarProperties {
|
||||||
|
|
||||||
|
public BarProperties(String foo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "bing")
|
||||||
|
public static class BingProperties {
|
||||||
|
|
||||||
|
public BingProperties() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BingProperties(String foo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2019 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
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.context.properties.scan.a;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Madhura Bhave
|
||||||
|
*/
|
||||||
|
public class AScanConfiguration {
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "a")
|
||||||
|
static class AProperties {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2019 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
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.context.properties.scan.b;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Madhura Bhave
|
||||||
|
*/
|
||||||
|
public class BScanConfiguration {
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "b")
|
||||||
|
static class BProperties {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue