From 136b1e8db84267eda1f4d3de6089f739b060f30b Mon Sep 17 00:00:00 2001
From: stvort
Date: Thu, 5 Sep 2019 22:37:27 +0400
Subject: [PATCH] 2019-08-Spring-05 examples added
---
2019-08/spring-05/.gitignore | 4 +
.../application-events-demo/.gitignore | 32 ++++++++
.../spring-05/application-events-demo/pom.xml | 53 ++++++++++++
.../ApplicationEventsDemoApplication.java | 13 +++
.../events/EventsPublisher.java | 5 ++
.../events/HalfAGlassOfWaterEvent.java | 15 ++++
.../HalfAGlassOfWaterEventPublisher.java | 17 ++++
.../events/NegativeRespondent.java | 15 ++++
.../events/PositiveRespondent.java | 15 ++++
.../shell/ApplicationEventsCommands.java | 34 ++++++++
.../src/main/resources/application.yml | 3 +
.../spring-05/beans-lifecycle-demo/.gitignore | 32 ++++++++
.../spring-05/beans-lifecycle-demo/pom.xml | 48 +++++++++++
.../BeansLifecycleDemoApplication.java | 13 +++
.../domain/FriendPhoneNumber.java | 8 ++
.../domain/GirlfiendPhoneNumber.java | 11 +++
.../beanslifecycledemo/domain/Phone.java | 16 ++++
.../domain/PhoneNumber.java | 7 ++
.../CustomBeanFactoryPostProcessor.java | 30 +++++++
.../lifecycle/CustomBeanPostProcessor.java | 40 +++++++++
.../lifecycle/CustomLifeCycleBean.java | 42 ++++++++++
.../lifecycle/LifeCycleConfig.java | 27 +++++++
.../shell/LifecycleDemoCommands.java | 18 +++++
.../src/main/resources/application.yml | 8 ++
.../spring-05/beans-scopes-demo/.gitignore | 32 ++++++++
2019-08/spring-05/beans-scopes-demo/pom.xml | 48 +++++++++++
.../BeansScopesDemoApplication.java | 13 +++
.../controllers/GreetingController.java | 40 +++++++++
.../services/AbstractGreetingServiceImpl.java | 35 ++++++++
.../services/GreetingService.java | 6 ++
.../PrototypeGreetingServiceImpl.java | 9 +++
.../services/RequestGreetingServiceImpl.java | 11 +++
.../services/SessionGreetingServiceImpl.java | 11 +++
.../SingletonGreetingServiceImpl.java | 9 +++
.../src/main/resources/application.yml | 8 ++
.../src/main/resources/templates/index.html | 45 +++++++++++
.../conditional-and-profiles-demo/.gitignore | 32 ++++++++
.../conditional-and-profiles-demo/pom.xml | 81 +++++++++++++++++++
...ConditionalAndProfilesDemoApplication.java | 13 +++
.../model/Alexey.java | 14 ++++
.../model/Anna.java | 14 ++++
.../model/Oleg.java | 14 ++++
.../model/Peter.java | 15 ++++
.../model/Yana.java | 16 ++++
.../model/Yanis.java | 14 ++++
.../model/base/Friend.java | 5 ++
.../model/conditions/YanaConditions.java | 20 +++++
.../ConditionalAndProfilesDemoCommands.java | 21 +++++
.../src/main/resources/application.yml | 25 ++++++
...tionalAndProfilesDemoApplicationTests.java | 37 +++++++++
.../src/test/resources/application.yml | 7 ++
2019-08/spring-05/pom.xml | 20 +++++
.../test-configuration-demo/.gitignore | 32 ++++++++
.../spring-05/test-configuration-demo/pom.xml | 74 +++++++++++++++++
.../TestConfigurationDemoApplication.java | 15 ++++
.../family/FamilyMember.java | 5 ++
.../family/childrens/Son.java | 12 +++
.../family/parents/Father.java | 10 +++
.../family/parents/Mother.java | 12 +++
.../family/pets/Dog.java | 13 +++
.../demo1/NestedConfigurationDemoTest.java | 37 +++++++++
.../NestedTestConfigurationDemoTest.java | 37 +++++++++
.../demo1/PlainSpringBootTestDemoTest.java | 26 ++++++
...ootTestWithExternalLimitationDemoTest.java | 26 ++++++
.../demo2/TestSpringBootConfiguration.java | 17 ++++
65 files changed, 1437 insertions(+)
create mode 100644 2019-08/spring-05/.gitignore
create mode 100644 2019-08/spring-05/application-events-demo/.gitignore
create mode 100644 2019-08/spring-05/application-events-demo/pom.xml
create mode 100644 2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/ApplicationEventsDemoApplication.java
create mode 100644 2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/EventsPublisher.java
create mode 100644 2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEvent.java
create mode 100644 2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEventPublisher.java
create mode 100644 2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/NegativeRespondent.java
create mode 100644 2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/PositiveRespondent.java
create mode 100644 2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shell/ApplicationEventsCommands.java
create mode 100644 2019-08/spring-05/application-events-demo/src/main/resources/application.yml
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/.gitignore
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/pom.xml
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/BeansLifecycleDemoApplication.java
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/FriendPhoneNumber.java
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/GirlfiendPhoneNumber.java
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/Phone.java
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/PhoneNumber.java
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomBeanFactoryPostProcessor.java
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomBeanPostProcessor.java
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomLifeCycleBean.java
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/LifeCycleConfig.java
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/shell/LifecycleDemoCommands.java
create mode 100644 2019-08/spring-05/beans-lifecycle-demo/src/main/resources/application.yml
create mode 100644 2019-08/spring-05/beans-scopes-demo/.gitignore
create mode 100644 2019-08/spring-05/beans-scopes-demo/pom.xml
create mode 100644 2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/BeansScopesDemoApplication.java
create mode 100644 2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/controllers/GreetingController.java
create mode 100644 2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/AbstractGreetingServiceImpl.java
create mode 100644 2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/GreetingService.java
create mode 100644 2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/PrototypeGreetingServiceImpl.java
create mode 100644 2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/RequestGreetingServiceImpl.java
create mode 100644 2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/SessionGreetingServiceImpl.java
create mode 100644 2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/SingletonGreetingServiceImpl.java
create mode 100644 2019-08/spring-05/beans-scopes-demo/src/main/resources/application.yml
create mode 100644 2019-08/spring-05/beans-scopes-demo/src/main/resources/templates/index.html
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/.gitignore
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/pom.xml
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/ConditionalAndProfilesDemoApplication.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Alexey.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Anna.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Oleg.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Peter.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yana.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yanis.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/base/Friend.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/conditions/YanaConditions.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/shell/ConditionalAndProfilesDemoCommands.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/main/resources/application.yml
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/test/java/ru/otus/example/conditionalandprofilesdemo/test/ConditionalAndProfilesDemoApplicationTests.java
create mode 100644 2019-08/spring-05/conditional-and-profiles-demo/src/test/resources/application.yml
create mode 100644 2019-08/spring-05/pom.xml
create mode 100644 2019-08/spring-05/test-configuration-demo/.gitignore
create mode 100644 2019-08/spring-05/test-configuration-demo/pom.xml
create mode 100644 2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java
create mode 100644 2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java
create mode 100644 2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java
create mode 100644 2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java
create mode 100644 2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java
create mode 100644 2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java
create mode 100644 2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/NestedConfigurationDemoTest.java
create mode 100644 2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/NestedTestConfigurationDemoTest.java
create mode 100644 2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/PlainSpringBootTestDemoTest.java
create mode 100644 2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo2/SpringBootTestWithExternalLimitationDemoTest.java
create mode 100644 2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo2/TestSpringBootConfiguration.java
diff --git a/2019-08/spring-05/.gitignore b/2019-08/spring-05/.gitignore
new file mode 100644
index 00000000..e62c33c2
--- /dev/null
+++ b/2019-08/spring-05/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+*.iml
+
+target/
diff --git a/2019-08/spring-05/application-events-demo/.gitignore b/2019-08/spring-05/application-events-demo/.gitignore
new file mode 100644
index 00000000..789ddc9e
--- /dev/null
+++ b/2019-08/spring-05/application-events-demo/.gitignore
@@ -0,0 +1,32 @@
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+#other
+*.bat
+*/.idea
+*.iml
+*/target
+
+.idea
+*.iml
+target
\ No newline at end of file
diff --git a/2019-08/spring-05/application-events-demo/pom.xml b/2019-08/spring-05/application-events-demo/pom.xml
new file mode 100644
index 00000000..415292a8
--- /dev/null
+++ b/2019-08/spring-05/application-events-demo/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.7.RELEASE
+
+
+
+ ru.otus.example
+ application-events-demo
+ 0.0.1-SNAPSHOT
+ application-events-demo
+ Application events demo
+
+
+ 11
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ org.springframework.shell
+ spring-shell-starter
+ 2.0.1.RELEASE
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/ApplicationEventsDemoApplication.java b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/ApplicationEventsDemoApplication.java
new file mode 100644
index 00000000..3e86cb07
--- /dev/null
+++ b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/ApplicationEventsDemoApplication.java
@@ -0,0 +1,13 @@
+package ru.otus.example.applicationeventsdemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ApplicationEventsDemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ApplicationEventsDemoApplication.class, args);
+ }
+
+}
diff --git a/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/EventsPublisher.java b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/EventsPublisher.java
new file mode 100644
index 00000000..2274570a
--- /dev/null
+++ b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/EventsPublisher.java
@@ -0,0 +1,5 @@
+package ru.otus.example.applicationeventsdemo.events;
+
+public interface EventsPublisher {
+ void publish();
+}
diff --git a/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEvent.java b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEvent.java
new file mode 100644
index 00000000..22bab552
--- /dev/null
+++ b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEvent.java
@@ -0,0 +1,15 @@
+package ru.otus.example.applicationeventsdemo.events;
+
+import lombok.Getter;
+import org.springframework.context.ApplicationEvent;
+
+public class HalfAGlassOfWaterEvent extends ApplicationEvent {
+
+ @Getter
+ private final String payload;
+
+ public HalfAGlassOfWaterEvent(Object source) {
+ super(source);
+ payload = "Осталось половина стакана воды!!!";
+ }
+}
diff --git a/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEventPublisher.java b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEventPublisher.java
new file mode 100644
index 00000000..a1186fcc
--- /dev/null
+++ b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/HalfAGlassOfWaterEventPublisher.java
@@ -0,0 +1,17 @@
+package ru.otus.example.applicationeventsdemo.events;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class HalfAGlassOfWaterEventPublisher implements EventsPublisher {
+
+ private final ApplicationEventPublisher publisher;
+
+ @Override
+ public void publish() {
+ publisher.publishEvent(new HalfAGlassOfWaterEvent(this));
+ }
+}
diff --git a/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/NegativeRespondent.java b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/NegativeRespondent.java
new file mode 100644
index 00000000..3e0be31a
--- /dev/null
+++ b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/NegativeRespondent.java
@@ -0,0 +1,15 @@
+package ru.otus.example.applicationeventsdemo.events;
+
+import org.springframework.context.ApplicationListener;
+import org.springframework.stereotype.Component;
+
+@Component
+public class NegativeRespondent implements ApplicationListener {
+
+ @Override
+ public void onApplicationEvent(HalfAGlassOfWaterEvent halfAGlassOfWaterEvent) {
+ System.out.println("Негативно настроенный слушатель");
+ System.out.println(String.format("- %s", halfAGlassOfWaterEvent.getPayload()));
+ System.out.println("- Какой ужас. Теперь он наполовину пуст!!!\n\n");
+ }
+}
diff --git a/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/PositiveRespondent.java b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/PositiveRespondent.java
new file mode 100644
index 00000000..60b9b649
--- /dev/null
+++ b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/events/PositiveRespondent.java
@@ -0,0 +1,15 @@
+package ru.otus.example.applicationeventsdemo.events;
+
+import org.springframework.context.ApplicationListener;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PositiveRespondent implements ApplicationListener {
+
+ @Override
+ public void onApplicationEvent(HalfAGlassOfWaterEvent halfAGlassOfWaterEvent) {
+ System.out.println("Позитивно настроенный слушатель");
+ System.out.println(String.format("- %s", halfAGlassOfWaterEvent.getPayload()));
+ System.out.println("- Ничего. Главное, что он наполовину полон!!!\n\n");
+ }
+}
diff --git a/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shell/ApplicationEventsCommands.java b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shell/ApplicationEventsCommands.java
new file mode 100644
index 00000000..03052027
--- /dev/null
+++ b/2019-08/spring-05/application-events-demo/src/main/java/ru/otus/example/applicationeventsdemo/shell/ApplicationEventsCommands.java
@@ -0,0 +1,34 @@
+package ru.otus.example.applicationeventsdemo.shell;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.shell.Availability;
+import org.springframework.shell.standard.ShellComponent;
+import org.springframework.shell.standard.ShellMethod;
+import org.springframework.shell.standard.ShellMethodAvailability;
+import org.springframework.shell.standard.ShellOption;
+import ru.otus.example.applicationeventsdemo.events.EventsPublisher;
+
+@ShellComponent
+@RequiredArgsConstructor
+public class ApplicationEventsCommands {
+
+ private final EventsPublisher eventsPublisher;
+
+ private String userName;
+
+ @ShellMethod(value = "Login command", key = {"l", "login"})
+ public String login(@ShellOption(defaultValue = "stvort") String userName) {
+ this.userName = userName;
+ return String.format("Добро пожаловать: %s", userName);
+ }
+
+ @ShellMethod(value = "Publish event command", key = {"p", "pub", "publish"})
+ @ShellMethodAvailability(value = "isPublishEventCommandAvailable")
+ public void publishEvent() {
+ eventsPublisher.publish();
+ }
+
+ private Availability isPublishEventCommandAvailable() {
+ return userName == null? Availability.unavailable("Сначала залогиньтесь"): Availability.available();
+ }
+}
diff --git a/2019-08/spring-05/application-events-demo/src/main/resources/application.yml b/2019-08/spring-05/application-events-demo/src/main/resources/application.yml
new file mode 100644
index 00000000..f78a9f36
--- /dev/null
+++ b/2019-08/spring-05/application-events-demo/src/main/resources/application.yml
@@ -0,0 +1,3 @@
+logging:
+ level:
+ root: ERROR
\ No newline at end of file
diff --git a/2019-08/spring-05/beans-lifecycle-demo/.gitignore b/2019-08/spring-05/beans-lifecycle-demo/.gitignore
new file mode 100644
index 00000000..789ddc9e
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/.gitignore
@@ -0,0 +1,32 @@
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+#other
+*.bat
+*/.idea
+*.iml
+*/target
+
+.idea
+*.iml
+target
\ No newline at end of file
diff --git a/2019-08/spring-05/beans-lifecycle-demo/pom.xml b/2019-08/spring-05/beans-lifecycle-demo/pom.xml
new file mode 100644
index 00000000..efd3c44e
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/pom.xml
@@ -0,0 +1,48 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.7.RELEASE
+
+
+ ru.otus.example
+ beans-lifecycle-demo
+ 0.0.1-SNAPSHOT
+ beans-lifecycle-demo
+ Beans lifecycle demo
+
+
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.shell
+ spring-shell-starter
+ 2.0.1.RELEASE
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/BeansLifecycleDemoApplication.java b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/BeansLifecycleDemoApplication.java
new file mode 100644
index 00000000..d3da1418
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/BeansLifecycleDemoApplication.java
@@ -0,0 +1,13 @@
+package ru.otus.example.beanslifecycledemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class BeansLifecycleDemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(BeansLifecycleDemoApplication.class, args);
+ }
+
+}
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/FriendPhoneNumber.java b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/FriendPhoneNumber.java
new file mode 100644
index 00000000..913d7db0
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/FriendPhoneNumber.java
@@ -0,0 +1,8 @@
+package ru.otus.example.beanslifecycledemo.domain;
+
+public class FriendPhoneNumber extends PhoneNumber {
+ @Override
+ public String getOwnerName() {
+ return "Друг";
+ }
+}
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/GirlfiendPhoneNumber.java b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/GirlfiendPhoneNumber.java
new file mode 100644
index 00000000..54e4e173
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/GirlfiendPhoneNumber.java
@@ -0,0 +1,11 @@
+package ru.otus.example.beanslifecycledemo.domain;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class GirlfiendPhoneNumber extends PhoneNumber {
+ @Override
+ public String getOwnerName() {
+ return "Подруга";
+ }
+}
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/Phone.java b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/Phone.java
new file mode 100644
index 00000000..b61d7fd7
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/Phone.java
@@ -0,0 +1,16 @@
+package ru.otus.example.beanslifecycledemo.domain;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class Phone {
+ private String greeting = "Погнали к родителям";
+
+ private final PhoneNumber favoriteNumber;
+
+ public void callFavoriteNumber() {
+ System.out.println(favoriteNumber.getOwnerName() + " " + greeting);
+ }
+}
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/PhoneNumber.java b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/PhoneNumber.java
new file mode 100644
index 00000000..215bd09f
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/domain/PhoneNumber.java
@@ -0,0 +1,7 @@
+package ru.otus.example.beanslifecycledemo.domain;
+
+public abstract class PhoneNumber {
+ public String getOwnerName() {
+ return "Спорт-лото";
+ }
+}
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomBeanFactoryPostProcessor.java b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomBeanFactoryPostProcessor.java
new file mode 100644
index 00000000..062f5bcc
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomBeanFactoryPostProcessor.java
@@ -0,0 +1,30 @@
+package ru.otus.example.beanslifecycledemo.lifecycle;
+
+import org.springframework.beans.BeanMetadataAttribute;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.annotation.ScannedGenericBeanDefinition;
+import ru.otus.example.beanslifecycledemo.domain.FriendPhoneNumber;
+import ru.otus.example.beanslifecycledemo.domain.GirlfiendPhoneNumber;
+
+public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+
+ if (beanFactory.containsBean("customLifeCycleBean")) {
+ System.out.println("Шаг #1: BeanFactoryPostProcessor.postProcessBeanFactory\n");
+ }
+
+ for (String beanName : beanFactory.getBeanDefinitionNames()) {
+ BeanDefinition d = beanFactory.getBeanDefinition(beanName);
+
+ if (GirlfiendPhoneNumber.class.getName().equalsIgnoreCase(d.getBeanClassName())) {
+ d.setBeanClassName(FriendPhoneNumber.class.getName());
+ ((ScannedGenericBeanDefinition) d).addMetadataAttribute(new BeanMetadataAttribute("className", FriendPhoneNumber.class.getName()));
+ d.setAutowireCandidate(true);
+ }
+ }
+ }
+}
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomBeanPostProcessor.java b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomBeanPostProcessor.java
new file mode 100644
index 00000000..9ce1dec0
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomBeanPostProcessor.java
@@ -0,0 +1,40 @@
+package ru.otus.example.beanslifecycledemo.lifecycle;
+
+import lombok.SneakyThrows;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import ru.otus.example.beanslifecycledemo.domain.Phone;
+
+import java.lang.reflect.Field;
+
+public class CustomBeanPostProcessor implements BeanPostProcessor {
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ if (bean.getClass().equals(CustomLifeCycleBean.class)) {
+ System.out.println("Шаг #5: BeanPostProcessor.postProcessBeforeInitialization\n");
+ }
+ return bean;
+ }
+
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ if (bean.getClass().equals(CustomLifeCycleBean.class)) {
+ System.out.println("Шаг #8: BeanPostProcessor.postProcessAfterInitialization\n");
+ }
+
+ if (bean.getClass().isAssignableFrom(Phone.class)) {
+ updateGreeting(bean);
+ }
+ return bean;
+ }
+
+ @SneakyThrows
+ private void updateGreeting(Object bean) {
+ Class aClass = Phone.class;
+ Field greetingField = aClass.getDeclaredField("greeting");
+
+ greetingField.setAccessible(true);
+ greetingField.setAccessible(true);
+ greetingField.set(bean, "Ай-да в гараж. Стихи читать!");
+ }
+}
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomLifeCycleBean.java b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomLifeCycleBean.java
new file mode 100644
index 00000000..1f9333e6
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/CustomLifeCycleBean.java
@@ -0,0 +1,42 @@
+package ru.otus.example.beanslifecycledemo.lifecycle;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.*;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public class CustomLifeCycleBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware {
+
+ @Override
+ public void setBeanName(String s) {
+ System.out.println("Шаг #2: BeanNameAware\n");
+ }
+
+ @Override
+ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+ System.out.println("Шаг #3: BeanFactoryAware\n");
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ System.out.println("Шаг #4: ApplicationContextAware\n");
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ System.out.println("Шаг #6: InitializingBean.afterPropertiesSet\n");
+ }
+
+ public void customInitMethod() throws Exception {
+ System.out.println("Шаг #7: CustomLifeCycleBean.customInitMethod\n");
+ }
+
+ @Override
+ public void destroy() throws Exception {
+ System.out.println("Шаг #9: DisposableBean.destroy\n");
+ }
+
+ public void customDestroyMethod() throws Exception {
+ System.out.println("Шаг #10: CustomLifeCycleBean.customDestroyMethod\n");
+ }
+}
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/LifeCycleConfig.java b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/LifeCycleConfig.java
new file mode 100644
index 00000000..bd81fea0
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/lifecycle/LifeCycleConfig.java
@@ -0,0 +1,27 @@
+package ru.otus.example.beanslifecycledemo.lifecycle;
+
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class LifeCycleConfig {
+
+ @Bean
+ public BeanFactoryPostProcessor customBeanFactoryPostProcessor() {
+ return new CustomBeanFactoryPostProcessor();
+ }
+
+ @Bean
+ public BeanPostProcessor customBeanPostProcessor() {
+ return new CustomBeanPostProcessor();
+ }
+
+ @ConditionalOnProperty(name = "spring.shell.interactive.enabled", havingValue = "false")
+ @Bean(initMethod = "customInitMethod", destroyMethod = "customDestroyMethod")
+ public CustomLifeCycleBean customLifeCycleBean() {
+ return new CustomLifeCycleBean();
+ }
+}
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/shell/LifecycleDemoCommands.java b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/shell/LifecycleDemoCommands.java
new file mode 100644
index 00000000..3987bc06
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/java/ru/otus/example/beanslifecycledemo/shell/LifecycleDemoCommands.java
@@ -0,0 +1,18 @@
+package ru.otus.example.beanslifecycledemo.shell;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.shell.standard.ShellComponent;
+import org.springframework.shell.standard.ShellMethod;
+import ru.otus.example.beanslifecycledemo.domain.Phone;
+
+@RequiredArgsConstructor
+@ShellComponent
+public class LifecycleDemoCommands {
+
+ private final Phone phone;
+
+ @ShellMethod(value = "Call favorite number", key = {"call-favorite-number", "cfn"})
+ public void callFavoriteNumber() {
+ phone.callFavoriteNumber();
+ }
+}
diff --git a/2019-08/spring-05/beans-lifecycle-demo/src/main/resources/application.yml b/2019-08/spring-05/beans-lifecycle-demo/src/main/resources/application.yml
new file mode 100644
index 00000000..a50954b5
--- /dev/null
+++ b/2019-08/spring-05/beans-lifecycle-demo/src/main/resources/application.yml
@@ -0,0 +1,8 @@
+logging:
+ level:
+ root: ERROR
+
+spring:
+ shell:
+ interactive:
+ enabled: false
diff --git a/2019-08/spring-05/beans-scopes-demo/.gitignore b/2019-08/spring-05/beans-scopes-demo/.gitignore
new file mode 100644
index 00000000..789ddc9e
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/.gitignore
@@ -0,0 +1,32 @@
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+#other
+*.bat
+*/.idea
+*.iml
+*/target
+
+.idea
+*.iml
+target
\ No newline at end of file
diff --git a/2019-08/spring-05/beans-scopes-demo/pom.xml b/2019-08/spring-05/beans-scopes-demo/pom.xml
new file mode 100644
index 00000000..e849c44c
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/pom.xml
@@ -0,0 +1,48 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.7.RELEASE
+
+
+
+ ru.otus.example
+ beans-scopes-demo
+ 0.0.1-SNAPSHOT
+ beans-scopes-demo
+ Beans scopes demo
+
+
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/BeansScopesDemoApplication.java b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/BeansScopesDemoApplication.java
new file mode 100644
index 00000000..a7ce4369
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/BeansScopesDemoApplication.java
@@ -0,0 +1,13 @@
+package ru.otus.example.beansscopesdemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class BeansScopesDemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(BeansScopesDemoApplication.class, args);
+ }
+
+}
diff --git a/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/controllers/GreetingController.java b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/controllers/GreetingController.java
new file mode 100644
index 00000000..1a309a90
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/controllers/GreetingController.java
@@ -0,0 +1,40 @@
+package ru.otus.example.beansscopesdemo.controllers;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import ru.otus.example.beansscopesdemo.services.GreetingService;
+
+@Controller
+public class GreetingController {
+ private final GreetingService singletonGreetingService;
+ private final GreetingService prototypeGreetingService1;
+ private final GreetingService prototypeGreetingService2;
+ private final GreetingService sessionGreetingService;
+ private final GreetingService requestGreetingService;
+
+ public GreetingController(@Qualifier("SingletonGreetingService") GreetingService singletonGreetingService,
+ @Qualifier("PrototypeGreetingService")GreetingService prototypeGreetingService1,
+ @Qualifier("PrototypeGreetingService")GreetingService prototypeGreetingService2,
+ @Qualifier("SessionGreetingService")GreetingService sessionGreetingService,
+ @Qualifier("RequestGreetingService")GreetingService requestGreetingService
+ ) {
+ this.singletonGreetingService = singletonGreetingService;
+ this.prototypeGreetingService1 = prototypeGreetingService1;
+ this.prototypeGreetingService2 = prototypeGreetingService2;
+ this.sessionGreetingService = sessionGreetingService;
+ this.requestGreetingService = requestGreetingService;
+ }
+
+ @GetMapping("/")
+ public String greetingPage(Model model) {
+ boolean isFirstGreetingSuccess = prototypeGreetingService1.isFirstGreetingSuccess();
+ model.addAttribute("singletonGreeting", singletonGreetingService.greeting());
+ model.addAttribute("sessionGreeting", sessionGreetingService.greeting());
+ model.addAttribute("requestGreeting", requestGreetingService.greeting());
+ model.addAttribute("prototype1Greeting", prototypeGreetingService1.greeting());
+ model.addAttribute("prototype2Greeting", isFirstGreetingSuccess? prototypeGreetingService2.greeting(): "Пока жду");
+ return "index";
+ }
+}
diff --git a/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/AbstractGreetingServiceImpl.java b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/AbstractGreetingServiceImpl.java
new file mode 100644
index 00000000..3fff2235
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/AbstractGreetingServiceImpl.java
@@ -0,0 +1,35 @@
+package ru.otus.example.beansscopesdemo.services;
+
+
+import org.springframework.beans.factory.annotation.Value;
+
+public abstract class AbstractGreetingServiceImpl implements GreetingService {
+
+ @Value("${greetings.first-greeting}")
+ private String firstGreeting;
+
+ @Value("${greetings.re-greeting}")
+ private String reGreeting;
+
+ private boolean isFirstGreetingSuccess;
+
+ public AbstractGreetingServiceImpl() {
+ this.isFirstGreetingSuccess = false;
+ }
+
+ @Override
+ public boolean isFirstGreetingSuccess() {
+ return isFirstGreetingSuccess;
+ }
+
+ @Override
+ public String greeting() {
+ return currentGreeting();
+ }
+
+ private synchronized String currentGreeting() {
+ String greeting = isFirstGreetingSuccess ? reGreeting : firstGreeting;
+ isFirstGreetingSuccess = true;
+ return greeting;
+ }
+}
diff --git a/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/GreetingService.java b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/GreetingService.java
new file mode 100644
index 00000000..1347ff39
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/GreetingService.java
@@ -0,0 +1,6 @@
+package ru.otus.example.beansscopesdemo.services;
+
+public interface GreetingService {
+ boolean isFirstGreetingSuccess();
+ String greeting();
+}
diff --git a/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/PrototypeGreetingServiceImpl.java b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/PrototypeGreetingServiceImpl.java
new file mode 100644
index 00000000..0932a66c
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/PrototypeGreetingServiceImpl.java
@@ -0,0 +1,9 @@
+package ru.otus.example.beansscopesdemo.services;
+
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+@Scope("prototype")
+@Service("PrototypeGreetingService")
+public class PrototypeGreetingServiceImpl extends AbstractGreetingServiceImpl {
+}
diff --git a/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/RequestGreetingServiceImpl.java b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/RequestGreetingServiceImpl.java
new file mode 100644
index 00000000..943c73db
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/RequestGreetingServiceImpl.java
@@ -0,0 +1,11 @@
+package ru.otus.example.beansscopesdemo.services;
+
+import org.springframework.context.annotation.Scope;
+import org.springframework.context.annotation.ScopedProxyMode;
+import org.springframework.stereotype.Service;
+import org.springframework.web.context.WebApplicationContext;
+
+@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
+@Service("RequestGreetingService")
+public class RequestGreetingServiceImpl extends AbstractGreetingServiceImpl {
+}
diff --git a/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/SessionGreetingServiceImpl.java b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/SessionGreetingServiceImpl.java
new file mode 100644
index 00000000..efff908a
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/SessionGreetingServiceImpl.java
@@ -0,0 +1,11 @@
+package ru.otus.example.beansscopesdemo.services;
+
+import org.springframework.context.annotation.Scope;
+import org.springframework.context.annotation.ScopedProxyMode;
+import org.springframework.stereotype.Service;
+import org.springframework.web.context.WebApplicationContext;
+
+@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
+@Service("SessionGreetingService")
+public class SessionGreetingServiceImpl extends AbstractGreetingServiceImpl {
+}
diff --git a/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/SingletonGreetingServiceImpl.java b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/SingletonGreetingServiceImpl.java
new file mode 100644
index 00000000..fb8406a5
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/src/main/java/ru/otus/example/beansscopesdemo/services/SingletonGreetingServiceImpl.java
@@ -0,0 +1,9 @@
+package ru.otus.example.beansscopesdemo.services;
+
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+@Scope("singleton")
+@Service("SingletonGreetingService")
+public class SingletonGreetingServiceImpl extends AbstractGreetingServiceImpl {
+}
diff --git a/2019-08/spring-05/beans-scopes-demo/src/main/resources/application.yml b/2019-08/spring-05/beans-scopes-demo/src/main/resources/application.yml
new file mode 100644
index 00000000..a18bec79
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/src/main/resources/application.yml
@@ -0,0 +1,8 @@
+greetings:
+ first-greeting: Привет
+ re-greeting: Рад снова тебя видеть
+
+
+logging:
+ level:
+ root: ERROR
\ No newline at end of file
diff --git a/2019-08/spring-05/beans-scopes-demo/src/main/resources/templates/index.html b/2019-08/spring-05/beans-scopes-demo/src/main/resources/templates/index.html
new file mode 100644
index 00000000..3719f228
--- /dev/null
+++ b/2019-08/spring-05/beans-scopes-demo/src/main/resources/templates/index.html
@@ -0,0 +1,45 @@
+
+
+
+
+ Advanced configuration demo
+
+
+
+
+
Демонстрация @Scope
+
+ - SingletonGreetingService должен говорить сначала "Привет", а потом все время "Рад снова тебя видеть"
+ - PrototypeGreetingService1 должен говорить сначала "Привет", а потом все время "Рад снова тебя видеть"
+ - PrototypeGreetingService2 должен говорить сначала "Пока жду", после обновления страницы "Привет", а потом все время "Рад снова тебя видеть"
+ - SessionGreetingService должен вести себя как SingletonGreetingService, но только до перезапуска браузера
+ - RequestGreetingService должен каждый раз говорить "Привет"
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/.gitignore b/2019-08/spring-05/conditional-and-profiles-demo/.gitignore
new file mode 100644
index 00000000..789ddc9e
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/.gitignore
@@ -0,0 +1,32 @@
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+#other
+*.bat
+*/.idea
+*.iml
+*/target
+
+.idea
+*.iml
+target
\ No newline at end of file
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/pom.xml b/2019-08/spring-05/conditional-and-profiles-demo/pom.xml
new file mode 100644
index 00000000..d14c448b
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/pom.xml
@@ -0,0 +1,81 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.7.RELEASE
+
+
+
+ ru.otus.example
+ conditional-and-profiles-demo
+ 0.0.1-SNAPSHOT
+ conditional-and-profiles-demo
+ Conditional and profiles demo
+
+
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+ junit
+ junit
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit-jupiter.version}
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit-jupiter.version}
+ test
+
+
+
+
+ org.springframework.shell
+ spring-shell-starter
+ 2.0.1.RELEASE
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/ConditionalAndProfilesDemoApplication.java b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/ConditionalAndProfilesDemoApplication.java
new file mode 100644
index 00000000..96f37fd9
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/ConditionalAndProfilesDemoApplication.java
@@ -0,0 +1,13 @@
+package ru.otus.example.conditionalandprofilesdemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ConditionalAndProfilesDemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ConditionalAndProfilesDemoApplication.class, args);
+ }
+
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Alexey.java b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Alexey.java
new file mode 100644
index 00000000..66091903
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Alexey.java
@@ -0,0 +1,14 @@
+package ru.otus.example.conditionalandprofilesdemo.model;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+import ru.otus.example.conditionalandprofilesdemo.model.base.Friend;
+
+@ConditionalOnProperty(name = "condition.alexey-exists", havingValue = "true")
+@Component
+public class Alexey extends Friend {
+ @Override
+ public String getName() {
+ return "Алексей";
+ }
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Anna.java b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Anna.java
new file mode 100644
index 00000000..be26e16d
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Anna.java
@@ -0,0 +1,14 @@
+package ru.otus.example.conditionalandprofilesdemo.model;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.stereotype.Component;
+import ru.otus.example.conditionalandprofilesdemo.model.base.Friend;
+
+@ConditionalOnBean(Alexey.class)
+@Component
+public class Anna extends Friend {
+ @Override
+ public String getName() {
+ return "Аня";
+ }
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Oleg.java b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Oleg.java
new file mode 100644
index 00000000..2a11f476
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Oleg.java
@@ -0,0 +1,14 @@
+package ru.otus.example.conditionalandprofilesdemo.model;
+
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Component;
+import ru.otus.example.conditionalandprofilesdemo.model.base.Friend;
+
+@Profile("Oleg")
+@Component
+public class Oleg extends Friend {
+ @Override
+ public String getName() {
+ return "Олег";
+ }
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Peter.java b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Peter.java
new file mode 100644
index 00000000..435891a8
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Peter.java
@@ -0,0 +1,15 @@
+package ru.otus.example.conditionalandprofilesdemo.model;
+
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Component;
+import ru.otus.example.conditionalandprofilesdemo.model.base.Friend;
+
+@Profile("Peter")
+@Component
+public class Peter extends Friend {
+
+ @Override
+ public String getName() {
+ return "Петр";
+ }
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yana.java b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yana.java
new file mode 100644
index 00000000..76b0fca3
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yana.java
@@ -0,0 +1,16 @@
+package ru.otus.example.conditionalandprofilesdemo.model;
+
+import org.springframework.context.annotation.Conditional;
+import org.springframework.stereotype.Component;
+import ru.otus.example.conditionalandprofilesdemo.model.base.Friend;
+import ru.otus.example.conditionalandprofilesdemo.model.conditions.YanaConditions;
+
+
+@Conditional(YanaConditions.class)
+@Component
+public class Yana extends Friend {
+ @Override
+ public String getName() {
+ return "Яна";
+ }
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yanis.java b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yanis.java
new file mode 100644
index 00000000..6dd2c14d
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/Yanis.java
@@ -0,0 +1,14 @@
+package ru.otus.example.conditionalandprofilesdemo.model;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+import ru.otus.example.conditionalandprofilesdemo.model.base.Friend;
+
+@ConditionalOnProperty(name = "condition.yanis-exists", havingValue = "true")
+@Component
+public class Yanis extends Friend {
+ @Override
+ public String getName() {
+ return "Янис";
+ }
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/base/Friend.java b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/base/Friend.java
new file mode 100644
index 00000000..2d2eb67d
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/base/Friend.java
@@ -0,0 +1,5 @@
+package ru.otus.example.conditionalandprofilesdemo.model.base;
+
+public abstract class Friend {
+ public abstract String getName();
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/conditions/YanaConditions.java b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/conditions/YanaConditions.java
new file mode 100644
index 00000000..cf130ebb
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/model/conditions/YanaConditions.java
@@ -0,0 +1,20 @@
+package ru.otus.example.conditionalandprofilesdemo.model.conditions;
+
+import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+public class YanaConditions extends AllNestedConditions {
+
+ public YanaConditions() {
+ super(ConfigurationPhase.PARSE_CONFIGURATION);
+ }
+
+
+ @ConditionalOnProperty(name = "condition.alexey-exists", havingValue = "false")
+ static class AlexeyDoesNotExistsCondition {
+ }
+
+ @ConditionalOnProperty(name = "condition.yanis-exists", havingValue = "true")
+ static class YanisExistsCondition {
+ }
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/shell/ConditionalAndProfilesDemoCommands.java b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/shell/ConditionalAndProfilesDemoCommands.java
new file mode 100644
index 00000000..a0cf3f0b
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/java/ru/otus/example/conditionalandprofilesdemo/shell/ConditionalAndProfilesDemoCommands.java
@@ -0,0 +1,21 @@
+package ru.otus.example.conditionalandprofilesdemo.shell;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.shell.standard.ShellComponent;
+import org.springframework.shell.standard.ShellMethod;
+import ru.otus.example.conditionalandprofilesdemo.model.base.Friend;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@ShellComponent
+@RequiredArgsConstructor
+public class ConditionalAndProfilesDemoCommands {
+
+ private final List partyMembers;
+
+ @ShellMethod(value = "Print party members", key = {"print-party-members", "ppm"})
+ public String printPartyMembers() {
+ return partyMembers.stream().map(Friend::getName).collect(Collectors.joining("\n"));
+ }
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/main/resources/application.yml b/2019-08/spring-05/conditional-and-profiles-demo/src/main/resources/application.yml
new file mode 100644
index 00000000..5045336c
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/main/resources/application.yml
@@ -0,0 +1,25 @@
+greetings:
+ first-greeting: Привет
+ re-greeting: Рад снова тебя видеть
+
+
+condition:
+ alexey-exists: true
+ yanis-exists: false
+
+spring:
+ profiles:
+ #active: Oleg
+ #active: Peter
+
+logging:
+ level:
+ root: ERROR
+
+
+---
+spring:
+ profiles: Peter
+
+condition:
+ yanis-exists: true
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/test/java/ru/otus/example/conditionalandprofilesdemo/test/ConditionalAndProfilesDemoApplicationTests.java b/2019-08/spring-05/conditional-and-profiles-demo/src/test/java/ru/otus/example/conditionalandprofilesdemo/test/ConditionalAndProfilesDemoApplicationTests.java
new file mode 100644
index 00000000..ccb1307b
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/test/java/ru/otus/example/conditionalandprofilesdemo/test/ConditionalAndProfilesDemoApplicationTests.java
@@ -0,0 +1,37 @@
+package ru.otus.example.conditionalandprofilesdemo.test;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import ru.otus.example.conditionalandprofilesdemo.model.base.Friend;
+
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+//@ActiveProfiles({"Oleg"})
+//@ActiveProfiles({"Peter"})
+//@ActiveProfiles({"Oleg", "Peter"})
+@DisplayName("FriendsMap должна")
+@SpringBootTest
+class ConditionalAndProfilesDemoApplicationTests {
+
+ @Autowired
+ private Map friendsMap;
+
+
+ @DisplayName(" содержать Олега")
+ @Test
+ void shouldContainOleg() {
+ assertThat(friendsMap).containsKey("oleg");
+ }
+
+ @DisplayName(" содержать Петра")
+ @Test
+ void shouldContainPetr() {
+ assertThat(friendsMap).containsKey("peter");
+ }
+
+}
diff --git a/2019-08/spring-05/conditional-and-profiles-demo/src/test/resources/application.yml b/2019-08/spring-05/conditional-and-profiles-demo/src/test/resources/application.yml
new file mode 100644
index 00000000..d1ae4f6e
--- /dev/null
+++ b/2019-08/spring-05/conditional-and-profiles-demo/src/test/resources/application.yml
@@ -0,0 +1,7 @@
+spring:
+ shell:
+ interactive:
+ enabled: false
+logging:
+ level:
+ root: ERROR
\ No newline at end of file
diff --git a/2019-08/spring-05/pom.xml b/2019-08/spring-05/pom.xml
new file mode 100644
index 00000000..eaebc07a
--- /dev/null
+++ b/2019-08/spring-05/pom.xml
@@ -0,0 +1,20 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-05
+ 1.0
+
+ pom
+
+
+ beans-scopes-demo
+ beans-lifecycle-demo
+ application-events-demo
+ conditional-and-profiles-demo
+ test-configuration-demo
+
+
diff --git a/2019-08/spring-05/test-configuration-demo/.gitignore b/2019-08/spring-05/test-configuration-demo/.gitignore
new file mode 100644
index 00000000..789ddc9e
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/.gitignore
@@ -0,0 +1,32 @@
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+#other
+*.bat
+*/.idea
+*.iml
+*/target
+
+.idea
+*.iml
+target
\ No newline at end of file
diff --git a/2019-08/spring-05/test-configuration-demo/pom.xml b/2019-08/spring-05/test-configuration-demo/pom.xml
new file mode 100644
index 00000000..5a986425
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/pom.xml
@@ -0,0 +1,74 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.7.RELEASE
+
+
+
+ ru.otus.example
+ test-configuration-demo
+ 0.0.1-SNAPSHOT
+ test-configuration-demo
+ Test configuration demo
+
+
+ 11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+ junit
+ junit
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit-jupiter.version}
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit-jupiter.version}
+ test
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java
new file mode 100644
index 00000000..e5dd8341
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/TestConfigurationDemoApplication.java
@@ -0,0 +1,15 @@
+package ru.otus.example.testconfigurationdemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@ComponentScan("ru.otus.example.testconfigurationdemo.family")
+@SpringBootApplication
+public class TestConfigurationDemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(TestConfigurationDemoApplication.class, args);
+ }
+
+}
diff --git a/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java
new file mode 100644
index 00000000..1685a4cc
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/FamilyMember.java
@@ -0,0 +1,5 @@
+package ru.otus.example.testconfigurationdemo.family;
+
+public abstract class FamilyMember {
+ public abstract String getName();
+}
diff --git a/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java
new file mode 100644
index 00000000..f3da3289
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/childrens/Son.java
@@ -0,0 +1,12 @@
+package ru.otus.example.testconfigurationdemo.family.childrens;
+
+import org.springframework.stereotype.Component;
+import ru.otus.example.testconfigurationdemo.family.FamilyMember;
+
+@Component
+public class Son extends FamilyMember {
+ @Override
+ public String getName() {
+ return "Сын";
+ }
+}
diff --git a/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java
new file mode 100644
index 00000000..d531bda5
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Father.java
@@ -0,0 +1,10 @@
+package ru.otus.example.testconfigurationdemo.family.parents;
+
+import ru.otus.example.testconfigurationdemo.family.FamilyMember;
+
+public class Father extends FamilyMember {
+ @Override
+ public String getName() {
+ return "Папа";
+ }
+}
diff --git a/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java
new file mode 100644
index 00000000..d9b97b75
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/parents/Mother.java
@@ -0,0 +1,12 @@
+package ru.otus.example.testconfigurationdemo.family.parents;
+
+import org.springframework.stereotype.Component;
+import ru.otus.example.testconfigurationdemo.family.FamilyMember;
+
+@Component
+public class Mother extends FamilyMember {
+ @Override
+ public String getName() {
+ return "Мама";
+ }
+}
diff --git a/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java
new file mode 100644
index 00000000..3e436c12
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/main/java/ru/otus/example/testconfigurationdemo/family/pets/Dog.java
@@ -0,0 +1,13 @@
+package ru.otus.example.testconfigurationdemo.family.pets;
+
+import org.springframework.stereotype.Component;
+import ru.otus.example.testconfigurationdemo.family.FamilyMember;
+
+@Component
+public class Dog extends FamilyMember {
+
+ @Override
+ public String getName() {
+ return "Собака";
+ }
+}
diff --git a/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/NestedConfigurationDemoTest.java b/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/NestedConfigurationDemoTest.java
new file mode 100644
index 00000000..ec5baa93
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/NestedConfigurationDemoTest.java
@@ -0,0 +1,37 @@
+package ru.otus.example.testconfigurationdemo.demo1;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import ru.otus.example.testconfigurationdemo.family.FamilyMember;
+import ru.otus.example.testconfigurationdemo.family.pets.Dog;
+
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@DisplayName("В NestedConfigurationDemoTest семья должна ")
+@SpringBootTest
+public class NestedConfigurationDemoTest {
+
+ @Configuration
+ static class NestedConfiguration {
+ @Bean
+ FamilyMember dog() {
+ return new Dog();
+ }
+ }
+
+ @Autowired
+ private Map family;
+
+ @DisplayName(" содержать только собаку ")
+ @Test
+ void shouldContainOnlyDog() {
+ assertThat(family).containsOnlyKeys("dog");
+ }
+
+}
diff --git a/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/NestedTestConfigurationDemoTest.java b/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/NestedTestConfigurationDemoTest.java
new file mode 100644
index 00000000..df8ee16f
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/NestedTestConfigurationDemoTest.java
@@ -0,0 +1,37 @@
+package ru.otus.example.testconfigurationdemo.demo1;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import ru.otus.example.testconfigurationdemo.family.FamilyMember;
+import ru.otus.example.testconfigurationdemo.family.parents.Father;
+
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@DisplayName("В NestedTestConfigurationDemoTest семья должна ")
+@SpringBootTest
+public class NestedTestConfigurationDemoTest {
+
+ @TestConfiguration
+ static class NestedTestConfiguration {
+ @Bean
+ FamilyMember father() {
+ return new Father();
+ }
+ }
+
+ @Autowired
+ private Map family;
+
+ @DisplayName(" содержать маму, папу, сына и собаку ")
+ @Test
+ void shouldContainAllFamilyWithFather() {
+ assertThat(family).containsOnlyKeys("mother", "father", "son", "dog");
+ }
+
+}
diff --git a/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/PlainSpringBootTestDemoTest.java b/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/PlainSpringBootTestDemoTest.java
new file mode 100644
index 00000000..07c32f59
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo1/PlainSpringBootTestDemoTest.java
@@ -0,0 +1,26 @@
+package ru.otus.example.testconfigurationdemo.demo1;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import ru.otus.example.testconfigurationdemo.family.FamilyMember;
+
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@DisplayName("В PlainSpringBootTestDemoTest семья должна ")
+@SpringBootTest
+public class PlainSpringBootTestDemoTest {
+
+ @Autowired
+ private Map family;
+
+ @DisplayName(" содержать маму, сына и собаку ")
+ @Test
+ void shouldContainAllFamilyExceptFather() {
+ assertThat(family).containsOnlyKeys("mother", "son", "dog");
+ }
+
+}
diff --git a/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo2/SpringBootTestWithExternalLimitationDemoTest.java b/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo2/SpringBootTestWithExternalLimitationDemoTest.java
new file mode 100644
index 00000000..98241b1b
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo2/SpringBootTestWithExternalLimitationDemoTest.java
@@ -0,0 +1,26 @@
+package ru.otus.example.testconfigurationdemo.demo2;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import ru.otus.example.testconfigurationdemo.family.FamilyMember;
+
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@DisplayName("В SpringBootTestWithExternalLimitationDemoTest семья должна ")
+@SpringBootTest
+public class SpringBootTestWithExternalLimitationDemoTest {
+
+ @Autowired
+ private Map family;
+
+ @DisplayName(" содержать маму, папу и сына")
+ @Test
+ void shouldContainAllFamilyExceptFather() {
+ assertThat(family).containsOnlyKeys("mother", "father", "son");
+ }
+
+}
diff --git a/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo2/TestSpringBootConfiguration.java b/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo2/TestSpringBootConfiguration.java
new file mode 100644
index 00000000..b4106d4b
--- /dev/null
+++ b/2019-08/spring-05/test-configuration-demo/src/test/java/ru/otus/example/testconfigurationdemo/demo2/TestSpringBootConfiguration.java
@@ -0,0 +1,17 @@
+package ru.otus.example.testconfigurationdemo.demo2;
+
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import ru.otus.example.testconfigurationdemo.family.FamilyMember;
+import ru.otus.example.testconfigurationdemo.family.parents.Father;
+
+@ComponentScan({"ru.otus.example.testconfigurationdemo.family.parents",
+ "ru.otus.example.testconfigurationdemo.family.childrens"})
+@SpringBootConfiguration
+public class TestSpringBootConfiguration {
+ @Bean
+ FamilyMember father() {
+ return new Father();
+ }
+}