WIP
authorKai Moritz <kai@juplo.de>
Fri, 20 Nov 2020 20:40:28 +0000 (21:40 +0100)
committerKai Moritz <kai@juplo.de>
Fri, 20 Nov 2020 22:01:09 +0000 (23:01 +0100)
src/main/java/de/juplo/demos/multiplebeans/MultipleBeansApplication.java
src/main/java/de/juplo/demos/multiplebeans/MultipleBeansBeanFactoryPostProcessor.java [new file with mode: 0644]
src/main/java/de/juplo/demos/multiplebeans/MultipleBeansProperties.java [new file with mode: 0644]
src/main/java/de/juplo/demos/multiplebeans/SiteController.java [new file with mode: 0644]
src/main/resources/400.html [new file with mode: 0644]
src/main/resources/application.properties [deleted file]
src/main/resources/application.yml [new file with mode: 0644]
src/main/resources/error.html [new file with mode: 0644]
src/main/resources/layout.html [new file with mode: 0644]
src/main/resources/view.html [new file with mode: 0644]

index 618ba8e..97cfb2a 100644 (file)
@@ -2,12 +2,14 @@ package de.juplo.demos.multiplebeans;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
 
 @SpringBootApplication
+@EnableConfigurationProperties(MultipleBeansProperties.class)
 public class MultipleBeansApplication {
 
+
        public static void main(String[] args) {
                SpringApplication.run(MultipleBeansApplication.class, args);
        }
-
 }
diff --git a/src/main/java/de/juplo/demos/multiplebeans/MultipleBeansBeanFactoryPostProcessor.java b/src/main/java/de/juplo/demos/multiplebeans/MultipleBeansBeanFactoryPostProcessor.java
new file mode 100644 (file)
index 0000000..0a89bcc
--- /dev/null
@@ -0,0 +1,30 @@
+package de.juplo.demos.multiplebeans;
+
+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.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MultipleBeansBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
+
+    public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
+
+        MultipleBeansProperties properties = factory.getBean(MultipleBeansProperties.class);
+        BeanDefinitionRegistry registry = (BeanDefinitionRegistry)factory;
+
+        for (MultipleBeansProperties.Site site : properties.site) {
+            BeanDefinition beanDefinition =
+                    BeanDefinitionBuilder
+                            .genericBeanDefinition(SiteController.class)
+                            .addConstructorArgValue(site.name)
+                            .addConstructorArgValue(site.description)
+                            .getBeanDefinition();
+
+            registry.registerBeanDefinition("name", beanDefinition);
+        }
+    }
+}
diff --git a/src/main/java/de/juplo/demos/multiplebeans/MultipleBeansProperties.java b/src/main/java/de/juplo/demos/multiplebeans/MultipleBeansProperties.java
new file mode 100644 (file)
index 0000000..f8384ff
--- /dev/null
@@ -0,0 +1,22 @@
+package de.juplo.demos.multiplebeans;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("de.juplo")
+@Getter
+@Setter
+public class MultipleBeansProperties {
+
+    Site[] site;
+
+
+    @Getter
+    @Setter
+    public static class Site {
+
+        String name;
+        String description;
+    }
+}
diff --git a/src/main/java/de/juplo/demos/multiplebeans/SiteController.java b/src/main/java/de/juplo/demos/multiplebeans/SiteController.java
new file mode 100644 (file)
index 0000000..dd6290b
--- /dev/null
@@ -0,0 +1,31 @@
+package de.juplo.demos.multiplebeans;
+
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.Controller;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class SiteController implements Controller {
+
+    private final String name;
+    private final String description;
+
+
+    public SiteController(String name, String description) {
+
+        this.name = name;
+        this.description = description;
+    }
+
+
+    public ModelAndView handleRequest(
+            HttpServletRequest request,
+            HttpServletResponse response) throws Exception {
+
+        ModelAndView mav = new ModelAndView("site");
+        mav.addObject("name", name);
+        mav.addObject("description", description);
+        return mav;
+    }
+}
diff --git a/src/main/resources/400.html b/src/main/resources/400.html
new file mode 100644 (file)
index 0000000..36ba0c0
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layout :: pagelayout(~{:: title}, ~{:: h1}, ~{:: div.card-text})}">
+  <head>
+    <title th:text="'400: ' + ${exception.getClass().getSimpleName()}">Testing Exception-Handling - Template for 400</title>
+    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  </head>
+  <body>
+    <h1 th:text="'400: ' + ${exception.getClass().getSimpleName()}">Template for 400</h1>
+    <div class="card-text table">
+      <p><strong th:text="'Catched exception: ' + ${exception}">EXCEPTION</strong></p>
+      <p><a href="#" th:href="@{/}" class="btn btn-primary">Back to HOME</a></p>
+    </div>
+  </body>
+</html>
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644 (file)
index 0000000..1f49f99
--- /dev/null
@@ -0,0 +1,10 @@
+de:
+  juplo:
+    site:
+      - name: peter
+        description: This is the Home-Page of PETER
+      - name: ute
+        description: My name is Ute. I like cats!
+      - name: franz
+        description: Franz was here!
+      
diff --git a/src/main/resources/error.html b/src/main/resources/error.html
new file mode 100644 (file)
index 0000000..a5e8149
--- /dev/null
@@ -0,0 +1,51 @@
+<!doctype html>
+<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layout :: pagelayout(~{:: title}, ~{:: h1}, ~{:: table.card-text})}">
+  <head>
+    <title th:text="|${status}: ${error}">XXX: ERROR</title>
+    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  </head>
+  <body>
+    <h1 th:text="|${status}: ${error}">XXX: ERROR</h1>
+      <table class="card-text table">
+        <tbody>
+          <tr class="border-top-0">
+            <th scope="row">Status</th>
+            <td th:text="${status}">ERROR.STATUS</td>
+          </tr>
+          <tr>
+            <th scope="row">Error</th>
+            <td th:text="${error}">ERROR.ERROR</td>
+          </tr>
+          <tr th:if="!${#strings.isEmpty(message)}">
+            <th scope="row">Message</th>
+            <td th:text="${message}">ERROR.MESSAGE</td>
+          </tr>
+          <tr th:if="!${#strings.isEmpty(requestId)}">
+            <th class="text-nowrap" scope="row">Request-ID</th>
+            <td th:text="${requestId}">ERROR.REQUEST_ID</td>
+          </tr>
+          <tr>
+            <th scope="row">Timstamp</th>
+            <td th:text="${timestamp}">ERROR.TIMESTAMP</td>
+          </tr>
+          <tr th:if="!${#strings.isEmpty(path)}">
+            <th scope="row">Path</th>
+            <td th:text="${path}">ERROR.PATH</td>
+          </tr>
+          <!--/**-->
+          <tr th:if="!${#strings.isEmpty(trace)}">
+            <th scope="row">Trace</th>
+            <td>
+              <div class="overflow-hidden">
+                <pre class="overflow-hidden" th:text="${trace}">ERROR.TRACE</pre>
+              </div>
+            </td>
+          </tr>
+          <!--**/-->
+        </tbody>
+      </table>
+      <p><a href="#" th:href="@{/}" class="btn btn-primary">Back to HOME</a>
+    </div>
+  </body>
+</html>
diff --git a/src/main/resources/layout.html b/src/main/resources/layout.html
new file mode 100644 (file)
index 0000000..3ad68ed
--- /dev/null
@@ -0,0 +1,20 @@
+<!doctype html>
+<html lang="en" xmlns:th="http://www.thymeleaf.org" th:fragment="pagelayout(title,header,body)">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <title th:replace="${title}">TITLE</title>
+    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.5.2/css/bootstrap.min.css}">
+  </head>
+  <body>
+    <nav class="navbar navbar-dark bg-primary navbar-expand navbar-dark flex-column">
+      <h2 class="navbar-brand">Demo: Creating Multiple Beans In Spring-Boot Pogrammatically</h2>
+    </nav>
+    <main class="container mt-5">
+      <div id="content" class="card">
+        <div class="card-header"><h1 th:replace="${header}">HEADER</h1></div>
+        <div class="card-body"><div th:replace="${body}">BODY</div></div>
+      </div>
+    </main>
+  </body>
+</html>
diff --git a/src/main/resources/view.html b/src/main/resources/view.html
new file mode 100644 (file)
index 0000000..2b66bb5
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layout :: pagelayout(~{:: title}, ~{:: h1}, ~{:: div.card-text})}">
+  <head>
+    <title th:text="${name}">SITE-TEMPLATE</title>
+    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  </head>
+  <body>
+    <h1 th:text="${name}">SITE</h1>
+    <div class="card-text">
+      <p th:text="${description}">DESCRIPTION</p>
+    </div>
+    <div class="card-text">
+      <p>
+        <em>
+          Each site is defined in the configuration with name and description inside an array.
+          This demo shows, how to create multiple beans of the same type based on the configuration.
+        </em>
+      </p>
+    </div>
+  </body>
+</html>