Merge branch 'master' of github.com:eugenp/tutorials into BAEL-3886
This commit is contained in:
commit
faf46dd544
|
@ -8,5 +8,4 @@ This module contains articles about Java 9 core features
|
|||
- [Introduction to Chronicle Queue](https://www.baeldung.com/java-chronicle-queue)
|
||||
- [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range)
|
||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
||||
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
|
||||
- [Immutable ArrayList in Java](https://www.baeldung.com/java-immutable-list)
|
||||
|
|
|
@ -11,3 +11,4 @@ This module contains articles about the Java Set collection
|
|||
- [Guide to EnumSet](https://www.baeldung.com/java-enumset)
|
||||
- [Set Operations in Java](https://www.baeldung.com/java-set-operations)
|
||||
- [Copying Sets in Java](https://www.baeldung.com/java-copy-sets)
|
||||
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
|
||||
|
|
|
@ -34,7 +34,23 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<commons-collections4.version>4.3</commons-collections4.version>
|
||||
<gson.version>2.8.5</gson.version>
|
||||
</properties>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.java9.set;
|
||||
package com.baeldung.set;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
package com.baeldung.java9;
|
||||
package com.baeldung.set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
*.class
|
||||
|
||||
0.*
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
.resourceCache
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# Files generated by integration tests
|
||||
*.txt
|
||||
backup-pom.xml
|
||||
/bin/
|
||||
/temp
|
||||
|
||||
#IntelliJ specific
|
||||
.idea/
|
||||
*.iml
|
|
@ -0,0 +1,7 @@
|
|||
=========
|
||||
|
||||
## Core Java Concurrency Testing Examples
|
||||
|
||||
### Relevant Articles:
|
||||
- [Testing Multi-Threaded Code in Java](https://www.baeldung.com/java-testing-multithreaded)
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-concurrency-testing</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-concurrency-testing</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.thread-weaver</groupId>
|
||||
<artifactId>threadweaver</artifactId>
|
||||
<version>0.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.tempus-fugit</groupId>
|
||||
<artifactId>tempus-fugit</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.multithreadedtc</groupId>
|
||||
<artifactId>multithreadedtc</artifactId>
|
||||
<version>1.01</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jcstress</groupId>
|
||||
<artifactId>jcstress-core</artifactId>
|
||||
<version>0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<compilerVersion>${javac.target}</compilerVersion>
|
||||
<source>${javac.target}</source>
|
||||
<target>${javac.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>main</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<finalName>jcstress</finalName>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>org.openjdk.jcstress.Main</mainClass>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/TestList</resource>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
public class MyCounter {
|
||||
|
||||
private int count;
|
||||
|
||||
public void increment() {
|
||||
int temp = count;
|
||||
count = temp + 1;
|
||||
}
|
||||
|
||||
public synchronized void incrementWithWait() throws InterruptedException {
|
||||
int temp = count;
|
||||
wait(100);
|
||||
count = temp + 1;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="WARN" />
|
||||
<logger name="org.springframework.transaction" level="WARN" />
|
||||
|
||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import static org.openjdk.jcstress.annotations.Expect.ACCEPTABLE;
|
||||
import static org.openjdk.jcstress.annotations.Expect.ACCEPTABLE_INTERESTING;
|
||||
|
||||
import org.openjdk.jcstress.annotations.Actor;
|
||||
import org.openjdk.jcstress.annotations.Arbiter;
|
||||
import org.openjdk.jcstress.annotations.JCStressTest;
|
||||
import org.openjdk.jcstress.annotations.Outcome;
|
||||
import org.openjdk.jcstress.annotations.State;
|
||||
import org.openjdk.jcstress.infra.results.I_Result;
|
||||
|
||||
@JCStressTest
|
||||
@Outcome(id = "1", expect = ACCEPTABLE_INTERESTING, desc = "One update lost.")
|
||||
@Outcome(id = "2", expect = ACCEPTABLE, desc = "Both updates.")
|
||||
@State
|
||||
public class MyCounterJCStressUnitTest {
|
||||
|
||||
private MyCounter counter;
|
||||
|
||||
@Actor
|
||||
public void actor1() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@Actor
|
||||
public void actor2() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@Arbiter
|
||||
public void arbiter(I_Result r) {
|
||||
r.r1 = counter.getCount();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import edu.umd.cs.mtc.MultithreadedTestCase;
|
||||
import edu.umd.cs.mtc.TestFramework;
|
||||
|
||||
public class MyCounterMultithreadedTCUnitTest extends MultithreadedTestCase {
|
||||
|
||||
private MyCounter counter;
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
counter = new MyCounter();
|
||||
}
|
||||
|
||||
public void thread1() throws InterruptedException {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
public void thread2() throws InterruptedException {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void finish() {
|
||||
assertEquals(2, counter.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCounter() throws Throwable {
|
||||
TestFramework.runManyTimes(new MyCounterMultithreadedTCUnitTest(), 1000);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class MyCounterSimpleUnitTest {
|
||||
|
||||
@Test
|
||||
public void testCounter() {
|
||||
MyCounter counter = new MyCounter();
|
||||
for (int i = 0; i < 500; i++)
|
||||
counter.increment();
|
||||
assertEquals(500, counter.getCount());
|
||||
}
|
||||
|
||||
// @Test
|
||||
public void testCounterWithConcurrency() throws InterruptedException {
|
||||
int numberOfThreads = 100;
|
||||
ExecutorService service = Executors.newFixedThreadPool(10);
|
||||
CountDownLatch latch = new CountDownLatch(numberOfThreads);
|
||||
MyCounter counter = new MyCounter();
|
||||
for (int i = 0; i < numberOfThreads; i++) {
|
||||
service.execute(() -> {
|
||||
counter.increment();
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
latch.await();
|
||||
assertEquals(numberOfThreads, counter.getCount());
|
||||
}
|
||||
|
||||
// @Test
|
||||
public void testSummationWithConcurrencyAndWait() throws InterruptedException {
|
||||
int numberOfThreads = 2;
|
||||
ExecutorService service = Executors.newFixedThreadPool(10);
|
||||
CountDownLatch latch = new CountDownLatch(numberOfThreads);
|
||||
MyCounter counter = new MyCounter();
|
||||
for (int i = 0; i < numberOfThreads; i++) {
|
||||
service.submit(() -> {
|
||||
try {
|
||||
counter.incrementWithWait();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
latch.await();
|
||||
assertEquals(numberOfThreads, counter.getCount());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.code.tempusfugit.concurrency.ConcurrentRule;
|
||||
import com.google.code.tempusfugit.concurrency.RepeatingRule;
|
||||
import com.google.code.tempusfugit.concurrency.annotations.Concurrent;
|
||||
import com.google.code.tempusfugit.concurrency.annotations.Repeating;
|
||||
|
||||
public class MyCounterTempusFugitUnitTest {
|
||||
|
||||
@Rule
|
||||
public ConcurrentRule concurrently = new ConcurrentRule();
|
||||
@Rule
|
||||
public RepeatingRule rule = new RepeatingRule();
|
||||
|
||||
private static MyCounter counter = new MyCounter();
|
||||
|
||||
@Test
|
||||
@Concurrent(count = 2)
|
||||
@Repeating(repetition = 10)
|
||||
public void runsMultipleTimes() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void annotatedTestRunsMultipleTimes() throws InterruptedException {
|
||||
assertEquals(counter.getCount(), 20);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.testing.threadtester.AnnotatedTestRunner;
|
||||
import com.google.testing.threadtester.ThreadedAfter;
|
||||
import com.google.testing.threadtester.ThreadedBefore;
|
||||
import com.google.testing.threadtester.ThreadedMain;
|
||||
import com.google.testing.threadtester.ThreadedSecondary;
|
||||
|
||||
public class MyCounterThreadWeaverUnitTest {
|
||||
|
||||
private MyCounter counter;
|
||||
|
||||
@ThreadedBefore
|
||||
public void before() {
|
||||
counter = new MyCounter();
|
||||
}
|
||||
|
||||
@ThreadedMain
|
||||
public void mainThread() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@ThreadedSecondary
|
||||
public void secondThread() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@ThreadedAfter
|
||||
public void after() {
|
||||
assertEquals(2, counter.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCounter() {
|
||||
new AnnotatedTestRunner().runTests(this.getClass(), MyCounter.class);
|
||||
}
|
||||
|
||||
}
|
13
core-java-modules/core-java-concurrency-testing/src/test/resources/.gitignore
vendored
Normal file
13
core-java-modules/core-java-concurrency-testing/src/test/resources/.gitignore
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
|
@ -38,6 +38,11 @@ public class AddingNewLineToString {
|
|||
System.out.println("6. Using System.getProperty(\"line.separator\")");
|
||||
rhyme = line1 + System.getProperty("line.separator") + line2;
|
||||
System.out.println(rhyme);
|
||||
|
||||
//7. Using %n
|
||||
System.out.println("7. Using %n");
|
||||
rhyme = "Humpty Dumpty sat on a wall.%nHumpty Dumpty had a great fall.";
|
||||
System.out.println(rhyme);
|
||||
|
||||
System.out.println("***HTML to rendered in a browser***");
|
||||
//1. Line break for HTML using <br>
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
<module>core-java-collections-list</module>
|
||||
<module>core-java-collections-list-2</module>
|
||||
<module>core-java-collections-list-3</module>
|
||||
<module>core-java-collections-set</module>
|
||||
<!-- <module>core-java-collections-set</module> --> <!-- We haven't upgraded to java 11. Fixing in BAEL-10841 -->
|
||||
|
||||
<module>core-java-concurrency-2</module>
|
||||
<module>core-java-concurrency-advanced</module>
|
||||
|
|
|
@ -10,10 +10,18 @@ import org.junit.Test;
|
|||
import java.io.IOException;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* Tests which show issues with JGit that we reported upstream.
|
||||
*/
|
||||
public class JGitBugIntegrationTest {
|
||||
public class JGitBugManualTest {
|
||||
|
||||
/**
|
||||
* This test case expects one git repository to be present in local file system.
|
||||
* Currently this test uses the Baeldung repository i.e. the current checkout repository.
|
||||
* It finds the repository by tracking back and scan file system to find .git folder in
|
||||
* the file system.
|
||||
*
|
||||
* Before running the test case ensure that the .git folder is present.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testRevWalkDisposeClosesReader() throws IOException {
|
||||
try (Repository repo = Helper.openJGitRepository()) {
|
|
@ -5,6 +5,7 @@ spring.datasource.password=
|
|||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
spring.h2.console.enabled=true
|
||||
spring.h2.console.path=/h2-console
|
||||
spring.datasource.data=data-trans.sql
|
||||
|
||||
logging.level.org.hibernate.SQL=INFO
|
||||
logging.level.org.hibernate.type=TRACE
|
||||
|
|
|
@ -5,6 +5,7 @@ spring.datasource.password=
|
|||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
spring.h2.console.enabled=true
|
||||
spring.h2.console.path=/h2-console
|
||||
spring.datasource.data=data-trans.sql
|
||||
|
||||
logging.level.org.hibernate.SQL=INFO
|
||||
logging.level.org.hibernate.type=TRACE
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -729,6 +729,7 @@
|
|||
<module>spring-threads</module>
|
||||
<module>spring-thymeleaf</module>
|
||||
<module>spring-thymeleaf-2</module>
|
||||
<module>spring-thymeleaf-3</module>
|
||||
|
||||
<module>spring-vault</module>
|
||||
<module>spring-vertx</module>
|
||||
|
@ -1229,6 +1230,7 @@
|
|||
|
||||
<module>spring-thymeleaf</module>
|
||||
<module>spring-thymeleaf-2</module>
|
||||
<module>spring-thymeleaf-3</module>
|
||||
|
||||
<module>spring-vault</module>
|
||||
<module>spring-vertx</module>
|
||||
|
|
|
@ -42,6 +42,11 @@
|
|||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>${byte-buddy.version}</version>
|
||||
</dependency>
|
||||
<!--kotlin deps -->
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
|
@ -175,8 +180,8 @@
|
|||
<jayway-rest-assured.version>2.9.0</jayway-rest-assured.version>
|
||||
<jackson.version>2.9.9</jackson.version> <!-- Same as spring-boot-dependencies:2.1.7.RELEASE -->
|
||||
<kotlin.version>1.2.71</kotlin.version> <!-- Same as spring-boot-dependencies:2.1.7.RELEASE -->
|
||||
<start-class>com.baeldung.Spring5Application</start-class>
|
||||
<httpclient.version>4.5.8</httpclient.version>
|
||||
<start-class>com.baeldung.Spring5Application</start-class>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
server.port=8081
|
||||
|
||||
security.user.name=user
|
||||
security.user.password=pass
|
||||
|
||||
logging.level.root=INFO
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.ioccontainer.bean;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
|
||||
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
|
||||
private static boolean isBeanFactoryPostProcessorRegistered = false;
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory){
|
||||
setBeanFactoryPostProcessorRegistered(true);
|
||||
}
|
||||
|
||||
public static boolean isBeanFactoryPostProcessorRegistered() {
|
||||
return isBeanFactoryPostProcessorRegistered;
|
||||
}
|
||||
|
||||
public static void setBeanFactoryPostProcessorRegistered(boolean isBeanFactoryPostProcessorRegistered) {
|
||||
CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered = isBeanFactoryPostProcessorRegistered;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.ioccontainer.bean;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
|
||||
public class CustomBeanPostProcessor implements BeanPostProcessor {
|
||||
private static boolean isBeanPostProcessorRegistered = false;
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName){
|
||||
setBeanPostProcessorRegistered(true);
|
||||
return bean;
|
||||
}
|
||||
|
||||
public static boolean isBeanPostProcessorRegistered() {
|
||||
return isBeanPostProcessorRegistered;
|
||||
}
|
||||
|
||||
public static void setBeanPostProcessorRegistered(boolean isBeanPostProcessorRegistered) {
|
||||
CustomBeanPostProcessor.isBeanPostProcessorRegistered = isBeanPostProcessorRegistered;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.ioccontainer.bean;
|
||||
|
||||
public class Student {
|
||||
private static boolean isBeanInstantiated = false;
|
||||
|
||||
public void postConstruct() {
|
||||
setBeanInstantiated(true);
|
||||
}
|
||||
|
||||
public static boolean isBeanInstantiated() {
|
||||
return isBeanInstantiated;
|
||||
}
|
||||
|
||||
public static void setBeanInstantiated(boolean isBeanInstantiated) {
|
||||
Student.isBeanInstantiated = isBeanInstantiated;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.baeldung.ioccontainer;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import com.baeldung.ioccontainer.bean.CustomBeanFactoryPostProcessor;
|
||||
import com.baeldung.ioccontainer.bean.CustomBeanPostProcessor;
|
||||
import com.baeldung.ioccontainer.bean.Student;
|
||||
|
||||
public class IOCContainerAppUnitTest {
|
||||
|
||||
@BeforeEach
|
||||
@AfterEach
|
||||
public void resetInstantiationFlag() {
|
||||
Student.setBeanInstantiated(false);
|
||||
CustomBeanPostProcessor.setBeanPostProcessorRegistered(false);
|
||||
CustomBeanFactoryPostProcessor.setBeanFactoryPostProcessorRegistered(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenBFInitialized_thenStudentNotInitialized() {
|
||||
Resource res = new ClassPathResource("ioc-container-difference-example.xml");
|
||||
BeanFactory factory = new XmlBeanFactory(res);
|
||||
|
||||
assertFalse(Student.isBeanInstantiated());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenBFInitialized_thenStudentInitialized() {
|
||||
Resource res = new ClassPathResource("ioc-container-difference-example.xml");
|
||||
BeanFactory factory = new XmlBeanFactory(res);
|
||||
Student student = (Student) factory.getBean("student");
|
||||
|
||||
assertTrue(Student.isBeanInstantiated());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAppContInitialized_thenStudentInitialized() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext("ioc-container-difference-example.xml");
|
||||
|
||||
assertTrue(Student.isBeanInstantiated());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenBFInitialized_thenBFPProcessorAndBPProcessorNotRegAutomatically() {
|
||||
Resource res = new ClassPathResource("ioc-container-difference-example.xml");
|
||||
ConfigurableListableBeanFactory factory = new XmlBeanFactory(res);
|
||||
|
||||
assertFalse(CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered());
|
||||
assertFalse(CustomBeanPostProcessor.isBeanPostProcessorRegistered());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenBFPostProcessorAndBPProcessorRegisteredManually_thenReturnTrue() {
|
||||
Resource res = new ClassPathResource("ioc-container-difference-example.xml");
|
||||
ConfigurableListableBeanFactory factory = new XmlBeanFactory(res);
|
||||
|
||||
CustomBeanFactoryPostProcessor beanFactoryPostProcessor = new CustomBeanFactoryPostProcessor();
|
||||
beanFactoryPostProcessor.postProcessBeanFactory(factory);
|
||||
assertTrue(CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered());
|
||||
|
||||
CustomBeanPostProcessor beanPostProcessor = new CustomBeanPostProcessor();
|
||||
factory.addBeanPostProcessor(beanPostProcessor);
|
||||
Student student = (Student) factory.getBean("student");
|
||||
assertTrue(CustomBeanPostProcessor.isBeanPostProcessorRegistered());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAppContInitialized_thenBFPostProcessorAndBPostProcessorRegisteredAutomatically() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext("ioc-container-difference-example.xml");
|
||||
|
||||
assertTrue(CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered());
|
||||
assertTrue(CustomBeanPostProcessor.isBeanPostProcessorRegistered());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||
|
||||
<bean id="student" class="com.baeldung.ioccontainer.bean.Student" init-method="postConstruct"/>
|
||||
<bean id="customBeanPostProcessor" class="com.baeldung.ioccontainer.bean.CustomBeanPostProcessor" />
|
||||
<bean id="customBeanFactoryPostProcessor" class="com.baeldung.ioccontainer.bean.CustomBeanFactoryPostProcessor" />
|
||||
</beans>
|
|
@ -0,0 +1,5 @@
|
|||
## Spring Thymeleaf 3
|
||||
|
||||
This module contains articles about Spring with Thymeleaf
|
||||
|
||||
## Relevant Articles:
|
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-thymeleaf-3</artifactId>
|
||||
<name>spring-thymeleaf-3</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.baeldung.thymeleaf.cssandjs.CssAndJsApplication</mainClass>
|
||||
<layout>JAR</layout>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.tomcat.maven</groupId>
|
||||
<artifactId>tomcat7-maven-plugin</artifactId>
|
||||
<version>${tomcat7-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>tomcat-run</id>
|
||||
<goals>
|
||||
<goal>exec-war-only</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
<configuration>
|
||||
<path>/</path>
|
||||
<enableNaming>false</enableNaming>
|
||||
<finalName>webapp.jar</finalName>
|
||||
<charset>utf-8</charset>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<finalName>spring-thymeleaf-3</finalName>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<tomcat7-maven-plugin.version>2.2</tomcat7-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.thymeleaf;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.thymeleaf.cssandjs;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class CssAndJsApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CssAndJsApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.thymeleaf.cssandjs;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class CssAndJsController {
|
||||
|
||||
@GetMapping("/styled-page")
|
||||
public String getStyledPage(Model model) {
|
||||
model.addAttribute("name", "Baeldung Reader");
|
||||
return "cssandjs/styledPage";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
function showAlert() {
|
||||
alert("The button was clicked!");
|
||||
}
|
||||
|
||||
function showName(name) {
|
||||
alert("Here's the name: " + name);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
h2 {
|
||||
font-family: sans-serif;
|
||||
font-size: 1.5em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: 600;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Add CSS and JS to Thymeleaf</title>
|
||||
<link th:href="@{/styles/cssandjs/main.css}" rel="stylesheet" />
|
||||
<script th:inline="javascript">
|
||||
var nameJs = /*[[${name}]]*/;
|
||||
</script>
|
||||
<script type="text/javascript" th:src="@{/js/cssandjs/actions.js}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Carefully Styled Heading</h2>
|
||||
<p>
|
||||
This is text on which we want to apply <strong>very special</strong> styling.
|
||||
</p>
|
||||
<p><label>Name:</label><span th:text="${name}"></span></p>
|
||||
<button type="button" th:onclick="showName(nameJs);">Show Name</button>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.thymeleaf;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
public class ApplicationIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.thymeleaf.cssandjs;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration(classes = CssAndJsApplication.class)
|
||||
public class CssAndJsControllerIntegrationTest {
|
||||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledGetStyledPage_thenReturnContent() throws Exception {
|
||||
this.mockMvc.perform(MockMvcRequestBuilders.get("/styled-page"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(view().name("cssandjs/styledPage"))
|
||||
.andExpect(content().string(containsString("Carefully Styled Heading")));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue