Compare commits
8 Commits
exercise-1
...
main
Author | SHA1 | Date |
---|---|---|
|
fa77e2057c | |
|
7626d5ccb3 | |
|
72de788456 | |
|
559600ca77 | |
|
d1cdd9e001 | |
|
c469b2a940 | |
|
1e2e977dda | |
|
7ccc2fb465 |
|
@ -17,17 +17,22 @@
|
|||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.workshop</groupId>
|
||||
<artifactId>library-api</artifactId>
|
||||
<artifactId>library-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<groupId>com.workshop</groupId>
|
||||
<artifactId>library-slf4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-properties-migrator</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -2,9 +2,7 @@ package com.workshop.magic.app;
|
|||
|
||||
import com.workshop.magic.service.AbstractGreetingService;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
//@Service
|
||||
class MyGreetingService extends AbstractGreetingService {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||
public class WorkshopApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("my.custom.condition", "true");
|
||||
SpringApplication.run(WorkshopApplication.class, args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
debug=false
|
||||
debug=true
|
||||
workshop.greeting.text=Gude
|
||||
workshop.greeting.type=none
|
||||
|
|
|
@ -13,4 +13,52 @@
|
|||
|
||||
<artifactId>library-autoconfigure</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.workshop</groupId>
|
||||
<artifactId>library-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.workshop</groupId>
|
||||
<artifactId>library-stdout</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.workshop</groupId>
|
||||
<artifactId>library-slf4j</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package com.workshop.magic.config;
|
||||
|
||||
import com.workshop.magic.service.GreetingService;
|
||||
import com.workshop.magic.service.slf4j.BeepGreetingService;
|
||||
import com.workshop.magic.service.slf4j.LoggerGreetingService;
|
||||
import com.workshop.magic.service.stdout.StdOutGreetingService;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass(GreetingService.class)
|
||||
@EnableConfigurationProperties(GreetingProperties.class)
|
||||
public class GreetingAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnClass(StdOutGreetingService.class)
|
||||
@ConditionalOnProperty(name = "workshop.greeting.type", havingValue = "stdout", matchIfMissing = true)
|
||||
GreetingService stdOutGreetingService(GreetingProperties properties) {
|
||||
return new StdOutGreetingService(properties.getPrefix());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnClass(LoggerGreetingService.class)
|
||||
@ConditionalOnProperty(name = "workshop.greeting.type", havingValue = "logger")
|
||||
GreetingService slf4jGreetingService(GreetingProperties properties) {
|
||||
return new LoggerGreetingService(properties.getPrefix());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@MyCustomCondition
|
||||
@ConditionalOnClass(BeepGreetingService.class)
|
||||
GreetingService beepGreetingService(GreetingProperties properties) {
|
||||
return new BeepGreetingService(properties.getPrefix());
|
||||
}
|
||||
}
|
|
@ -1,15 +1,21 @@
|
|||
package com.workshop.magic.config;
|
||||
|
||||
public class GreetingProperties {
|
||||
private String text = "Hello";
|
||||
private Type type = Type.STDOUT;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
|
||||
|
||||
@ConfigurationProperties(prefix = "workshop.greeting")
|
||||
public class GreetingProperties {
|
||||
private Type type = Type.STDOUT;
|
||||
private String prefix = "Hello";
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "workshop.greeting.prefix")
|
||||
@Deprecated
|
||||
public String getText() {
|
||||
return this.text;
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
this.prefix = text;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
|
@ -20,6 +26,14 @@ public class GreetingProperties {
|
|||
this.type = type;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
STDOUT,
|
||||
LOGGER,
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package com.workshop.magic.config;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Conditional({OnCustomCondition.class})
|
||||
@interface MyCustomCondition {
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.workshop.magic.config;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
class OnCustomCondition extends SpringBootCondition {
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
String value = System.getProperty("my.custom.condition");
|
||||
if (value == null) {
|
||||
return ConditionOutcome.noMatch("No 'my.custom.condition' system property found");
|
||||
}
|
||||
if (value.toLowerCase(Locale.ROOT).equals("true")) {
|
||||
return ConditionOutcome.match("'my.custom.condition' system property is true");
|
||||
}
|
||||
return ConditionOutcome.noMatch("'my.custom.condition' system property is '%s'".formatted(value));
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
com.workshop.magic.config.GreetingAutoConfiguration
|
|
@ -0,0 +1,101 @@
|
|||
package com.workshop.magic.config;
|
||||
|
||||
import com.workshop.magic.service.GreetingService;
|
||||
import com.workshop.magic.service.slf4j.BeepGreetingService;
|
||||
import com.workshop.magic.service.slf4j.LoggerGreetingService;
|
||||
import com.workshop.magic.service.stdout.StdOutGreetingService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class GreetingAutoConfigurationTest {
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(GreetingAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldProvideStdOutGreetingServiceByDefault() {
|
||||
this.contextRunner.run(context -> {
|
||||
assertThat(context).hasSingleBean(StdOutGreetingService.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProvideStdOutGreetingServiceWhenPropertyIsSet() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("workshop.greeting.type=stdout")
|
||||
.run(context -> {
|
||||
assertThat(context).hasSingleBean(StdOutGreetingService.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProvideLoggerGreetingServiceWhenPropertyIsSet() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("workshop.greeting.type=logger")
|
||||
.run(context -> {
|
||||
assertThat(context).hasSingleBean(LoggerGreetingService.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffIfGreetingServiceIsDefinedByUser() {
|
||||
this.contextRunner
|
||||
.withBean(GreetingService.class, UserGreetingService::new)
|
||||
.run(context -> {
|
||||
assertThat(context).hasSingleBean(GreetingService.class);
|
||||
assertThat(context).hasSingleBean(UserGreetingService.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotUseStdOutGreetingServiceIfNotOnClasspath() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("workshop.greeting.type=stdout")
|
||||
.withClassLoader(new FilteredClassLoader(StdOutGreetingService.class))
|
||||
.run(context -> {
|
||||
assertThat(context).doesNotHaveBean(GreetingService.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotUseLoggerGreetingServiceIfNotOnClasspath() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("workshop.greeting.type=logger")
|
||||
.withClassLoader(new FilteredClassLoader(LoggerGreetingService.class))
|
||||
.run(context -> {
|
||||
assertThat(context).doesNotHaveBean(GreetingService.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProvideBeepGreetingServiceIfSystemPropertyIsSet() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("workshop.greeting.type=none")
|
||||
.withSystemProperties("my.custom.condition=true")
|
||||
.run(context -> {
|
||||
assertThat(context).hasSingleBean(BeepGreetingService.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotUseBeepGreetingServiceIfNotOnClasspath() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("workshop.greeting.type=none")
|
||||
.withSystemProperties("my.custom.condition=true")
|
||||
.withClassLoader(new FilteredClassLoader(BeepGreetingService.class))
|
||||
.run(context -> {
|
||||
assertThat(context).doesNotHaveBean(GreetingService.class);
|
||||
});
|
||||
}
|
||||
|
||||
private static class UserGreetingService implements GreetingService {
|
||||
@Override
|
||||
public void greet(String name) {
|
||||
System.out.println("UserGreetingService: Hello " + name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,4 +12,23 @@
|
|||
|
||||
<artifactId>library-spring-boot-starter</artifactId>
|
||||
|
||||
</project>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.workshop</groupId>
|
||||
<artifactId>library-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.workshop</groupId>
|
||||
<artifactId>library-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.workshop</groupId>
|
||||
<artifactId>library-stdout</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
Loading…
Reference in New Issue