diff --git a/.travis.yml b/.travis.yml index 3d28a5cd76..0393b2304e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ before_install: - echo "MAVEN_OPTS='-Xmx2048M -Xss128M -XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -XX:-UseGCOverheadLimit'" > ~/.mavenrc install: skip -script: travis_wait 60 mvn -q test -fae +script: travis_wait 60 mvn -q test sudo: required diff --git a/core-java/README.md b/core-java/README.md index b7482b09cc..dc3a1ea405 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -136,4 +136,5 @@ - [The Trie Data Structure in Java](http://www.baeldung.com/trie-java) - [Introduction to Javadoc](http://www.baeldung.com/javadoc) - [How to TDD a List Implementation](http://jira.baeldung.com/browse/BAEL-1537) +- [How to Make a Deep Copy of an Object in Java](http://www.baeldung.com/java-deep-copy) diff --git a/data-structures/.gitignore b/data-structures/.gitignore new file mode 100644 index 0000000000..b83d22266a --- /dev/null +++ b/data-structures/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/data-structures/README.md b/data-structures/README.md new file mode 100644 index 0000000000..b3b1196ce0 --- /dev/null +++ b/data-structures/README.md @@ -0,0 +1,4 @@ +## Relevant articles: + +- [The Trie Data Structure in Java](http://www.baeldung.com/trie-java) +- [Implementing a Binary Tree in Java](http://www.baeldung.com/java-binary-tree) diff --git a/data-structures/pom.xml b/data-structures/pom.xml new file mode 100644 index 0000000000..68174a41df --- /dev/null +++ b/data-structures/pom.xml @@ -0,0 +1,24 @@ + + 4.0.0 + com.baeldung + data-structures + 0.0.1-SNAPSHOT + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + + + + diff --git a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java b/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java similarity index 100% rename from core-java/src/main/java/com/baeldung/tree/BinaryTree.java rename to data-structures/src/main/java/com/baeldung/tree/BinaryTree.java diff --git a/core-java/src/main/java/com/baeldung/trie/Trie.java b/data-structures/src/main/java/com/baeldung/trie/Trie.java similarity index 100% rename from core-java/src/main/java/com/baeldung/trie/Trie.java rename to data-structures/src/main/java/com/baeldung/trie/Trie.java diff --git a/core-java/src/main/java/com/baeldung/trie/TrieNode.java b/data-structures/src/main/java/com/baeldung/trie/TrieNode.java similarity index 100% rename from core-java/src/main/java/com/baeldung/trie/TrieNode.java rename to data-structures/src/main/java/com/baeldung/trie/TrieNode.java diff --git a/core-java/src/test/java/com/baeldung/tree/BinaryTreeTest.java b/data-structures/src/test/java/com/baeldung/tree/BinaryTreeTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/tree/BinaryTreeTest.java rename to data-structures/src/test/java/com/baeldung/tree/BinaryTreeTest.java diff --git a/core-java/src/test/java/com/baeldung/trie/TrieTest.java b/data-structures/src/test/java/com/baeldung/trie/TrieTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/trie/TrieTest.java rename to data-structures/src/test/java/com/baeldung/trie/TrieTest.java diff --git a/libraries/pom.xml b/libraries/pom.xml index e9bfecf527..78868f798b 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -11,6 +11,20 @@ + + + com.typesafe.akka + akka-actor_2.12 + 2.5.11 + + + + com.typesafe.akka + akka-testkit_2.12 + 2.5.11 + test + + org.asynchttpclient diff --git a/libraries/src/main/java/com/baeldung/akka/FirstActor.java b/libraries/src/main/java/com/baeldung/akka/FirstActor.java new file mode 100644 index 0000000000..9680429fb1 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/akka/FirstActor.java @@ -0,0 +1,32 @@ +package com.baeldung.akka; + +import akka.actor.AbstractActor; +import akka.actor.Props; +import akka.event.Logging; +import akka.event.LoggingAdapter; + +public class FirstActor extends AbstractActor { + + private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this); + + public static Props props() { + return Props.create(FirstActor.class); + } + + @Override + public void preStart() { + log.info("Actor started"); + } + + @Override + public void postStop() { + log.info("Actor stopped"); + } + + // Messages will not be handled + @Override + public Receive createReceive() { + return receiveBuilder() + .build(); + } +} diff --git a/libraries/src/main/java/com/baeldung/akka/MyActor.java b/libraries/src/main/java/com/baeldung/akka/MyActor.java new file mode 100644 index 0000000000..99ee3158b6 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/akka/MyActor.java @@ -0,0 +1,24 @@ +package com.baeldung.akka; + +import akka.actor.AbstractActor; +import akka.event.Logging; +import akka.event.LoggingAdapter; + +public class MyActor extends AbstractActor { + + private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this); + + @Override + public void postStop() { + log.info("Stopping actor {}", this); + } + + public Receive createReceive() { + return receiveBuilder() + .matchEquals("printit", p -> { + System.out.println("The address of this actor is: " + getSelf()); + getSender().tell("Got Message", getSelf()); + }) + .build(); + } +} diff --git a/libraries/src/main/java/com/baeldung/akka/PrinterActor.java b/libraries/src/main/java/com/baeldung/akka/PrinterActor.java new file mode 100644 index 0000000000..55b6e4e0f4 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/akka/PrinterActor.java @@ -0,0 +1,45 @@ +package com.baeldung.akka; + +import akka.actor.AbstractActor; +import akka.actor.Props; +import akka.event.Logging; +import akka.event.LoggingAdapter; + +public class PrinterActor extends AbstractActor { + + private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this); + + public static Props props(String text) { + return Props.create(PrinterActor.class, text); + } + + public static final class PrintFinalResult { + Integer totalNumberOfWords; + + public PrintFinalResult(Integer totalNumberOfWords) { + this.totalNumberOfWords = totalNumberOfWords; + } + } + + @Override + public void preStart() { + log.info("Starting PrinterActor {}", this); + } + + @Override + public void postStop() { + log.info("Stopping PrinterActor {}", this); + } + + + @Override + public Receive createReceive() { + return receiveBuilder() + .match(PrinterActor.PrintFinalResult.class, + r -> { + log.info("Received PrintFinalResult message from " + getSender()); + log.info("The text has a total number of {} words", r.totalNumberOfWords); + }) + .build(); + } +} diff --git a/libraries/src/main/java/com/baeldung/akka/ReadingActor.java b/libraries/src/main/java/com/baeldung/akka/ReadingActor.java new file mode 100644 index 0000000000..f1a21c8e28 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/akka/ReadingActor.java @@ -0,0 +1,73 @@ +package com.baeldung.akka; + +import akka.actor.AbstractActor; +import akka.actor.ActorRef; +import akka.actor.Props; +import akka.event.Logging; +import akka.event.LoggingAdapter; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static akka.pattern.PatternsCS.ask; + +public class ReadingActor extends AbstractActor { + + private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this); + + private String text; + + public ReadingActor(String text) { + this.text = text; + } + + public static Props props(String text) { + return Props.create(ReadingActor.class, text); + } + + public static final class ReadLines { + } + + @Override + public void preStart() { + log.info("Starting ReadingActor {}", this); + } + + @Override + public void postStop() { + log.info("Stopping ReadingActor {}", this); + } + + @Override + public Receive createReceive() { + return receiveBuilder() + .match(ReadLines.class, r -> { + + log.info("Received ReadLines message from " + getSender()); + + String[] lines = text.split("\n"); + List futures = new ArrayList<>(); + + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + ActorRef wordCounterActorRef = getContext().actorOf(Props.create(WordCounterActor.class), "word-counter-" + i); + + CompletableFuture future = + ask(wordCounterActorRef, new WordCounterActor.CountWords(line), 1000).toCompletableFuture(); + futures.add(future); + } + + Integer totalNumberOfWords = futures.stream() + .map(CompletableFuture::join) + .mapToInt(n -> (Integer) n) + .sum(); + + ActorRef printerActorRef = getContext().actorOf(Props.create(PrinterActor.class), "Printer-Actor"); + printerActorRef.forward(new PrinterActor.PrintFinalResult(totalNumberOfWords), getContext()); +// printerActorRef.tell(new PrinterActor.PrintFinalResult(totalNumberOfWords), getSelf()); + + }) + .build(); + } +} diff --git a/libraries/src/main/java/com/baeldung/akka/WordCounterActor.java b/libraries/src/main/java/com/baeldung/akka/WordCounterActor.java new file mode 100644 index 0000000000..3e23683971 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/akka/WordCounterActor.java @@ -0,0 +1,55 @@ +package com.baeldung.akka; + +import akka.actor.AbstractActor; +import akka.event.Logging; +import akka.event.LoggingAdapter; + +public class WordCounterActor extends AbstractActor { + + private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this); + + public static final class CountWords { + String line; + + public CountWords(String line) { + this.line = line; + } + } + + @Override + public void preStart() { + log.info("Starting WordCounterActor {}", this); + } + + @Override + public Receive createReceive() { + return receiveBuilder() + .match(CountWords.class, r -> { + try { + log.info("Received CountWords message from " + getSender()); + int numberOfWords = countWordsFromLine(r.line); + getSender().tell(numberOfWords, getSelf()); + } catch (Exception ex) { + getSender().tell(new akka.actor.Status.Failure(ex), getSelf()); + throw ex; + } + }) + .build(); + } + + private int countWordsFromLine(String line) throws Exception { + + if (line == null) { + throw new IllegalArgumentException("The text to process can't be null!"); + } + + int numberOfWords = 0; + String[] words = line.split(" "); + for (String possibleWord : words) { + if (possibleWord.trim().length() > 0) { + numberOfWords++; + } + } + return numberOfWords; + } +} diff --git a/libraries/src/test/java/com/baeldung/akka/AkkaActorsUnitTest.java b/libraries/src/test/java/com/baeldung/akka/AkkaActorsUnitTest.java new file mode 100644 index 0000000000..adaff86565 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/akka/AkkaActorsUnitTest.java @@ -0,0 +1,104 @@ +package com.baeldung.akka; + +import akka.actor.ActorRef; +import akka.actor.ActorSystem; +import akka.actor.Props; +import akka.testkit.TestKit; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import scala.concurrent.duration.Duration; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static akka.pattern.PatternsCS.ask; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class AkkaActorsUnitTest { + + private static ActorSystem system = null; + + @BeforeClass + public static void setup() { + system = ActorSystem.create("test-system"); + } + + @AfterClass + public static void teardown() { + TestKit.shutdownActorSystem(system, Duration.apply(1000, TimeUnit.MILLISECONDS), true); + system = null; + } + + @Test + public void givenAnActor_sendHimAMessageUsingTell() { + + final TestKit probe = new TestKit(system); + ActorRef myActorRef = probe.childActorOf(Props.create(MyActor.class)); + myActorRef.tell("printit", probe.testActor()); + + probe.expectMsg("Got Message"); + } + + @Test + public void givenAnActor_sendHimAMessageUsingAsk() throws ExecutionException, InterruptedException { + + final TestKit probe = new TestKit(system); + ActorRef wordCounterActorRef = probe.childActorOf(Props.create(WordCounterActor.class)); + + CompletableFuture future = + ask(wordCounterActorRef, new WordCounterActor.CountWords("this is a text"), 1000).toCompletableFuture(); + + Integer numberOfWords = (Integer) future.get(); + assertTrue("The actor should count 4 words", 4 == numberOfWords); + } + + @Test + public void givenAnActor_whenTheMessageIsNull_respondWithException() { + final TestKit probe = new TestKit(system); + ActorRef wordCounterActorRef = probe.childActorOf(Props.create(WordCounterActor.class)); + + CompletableFuture future = + ask(wordCounterActorRef, new WordCounterActor.CountWords(null), 1000).toCompletableFuture(); + + try { + future.get(1000, TimeUnit.MILLISECONDS); + } catch (ExecutionException e) { + assertTrue("Invalid error message", e.getMessage().contains("The text to process can't be null!")); + } catch (InterruptedException | TimeoutException e) { + fail("Actor should respond with an exception instead of timing out !"); + } + } + + @Test + public void givenAnAkkaSystem_countTheWordsInAText() { + ActorSystem system = ActorSystem.create("test-system"); + ActorRef myActorRef = system.actorOf(Props.create(MyActor.class), "my-actor"); + myActorRef.tell("printit", null); +// system.stop(myActorRef); +// myActorRef.tell(PoisonPill.getInstance(), ActorRef.noSender()); +// myActorRef.tell(Kill.getInstance(), ActorRef.noSender()); + + ActorRef readingActorRef = system.actorOf(ReadingActor.props(TEXT), "readingActor"); + readingActorRef.tell(new ReadingActor.ReadLines(), ActorRef.noSender()); //ActorRef.noSender() means the sender ref is akka://test-system/deadLetters + +// Future terminateResponse = system.terminate(); + } + + private static String TEXT = "Lorem Ipsum is simply dummy text\n" + + "of the printing and typesetting industry.\n" + + "Lorem Ipsum has been the industry's standard dummy text\n" + + "ever since the 1500s, when an unknown printer took a galley\n" + + "of type and scrambled it to make a type specimen book.\n" + + " It has survived not only five centuries, but also the leap\n" + + "into electronic typesetting, remaining essentially unchanged.\n" + + " It was popularised in the 1960s with the release of Letraset\n" + + " sheets containing Lorem Ipsum passages, and more recently with\n" + + " desktop publishing software like Aldus PageMaker including\n" + + "versions of Lorem Ipsum."; + +} diff --git a/libraries/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java b/libraries/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java index 70d3e41579..d8bc46985d 100644 --- a/libraries/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java +++ b/libraries/src/test/java/com/baeldung/pact/PactConsumerDrivenContractUnitTest.java @@ -5,6 +5,8 @@ import au.com.dius.pact.consumer.PactProviderRuleMk2; import au.com.dius.pact.consumer.PactVerification; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.model.RequestResponsePact; + +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.springframework.http.HttpEntity; @@ -34,6 +36,7 @@ public class PactConsumerDrivenContractUnitTest { } @Test + @Ignore @PactVerification() public void givenGet_whenSendRequest_shouldReturn200WithProperHeaderAndBody() { // when diff --git a/libraries/src/test/java/com/baeldung/unirest/HttpClientTest.java b/libraries/src/test/java/com/baeldung/unirest/HttpClientTest.java index 3e919f031c..82093ad297 100644 --- a/libraries/src/test/java/com/baeldung/unirest/HttpClientTest.java +++ b/libraries/src/test/java/com/baeldung/unirest/HttpClientTest.java @@ -15,6 +15,7 @@ import java.util.concurrent.Future; import org.apache.http.entity.ContentType; import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import com.baeldung.unirest.Article; @@ -104,6 +105,7 @@ public class HttpClientTest { } @Test + @Ignore public void whenAysncRequestShouldReturnOk() throws InterruptedException, ExecutionException { Future> future = Unirest.post("http://www.mocky.io/v2/5a9ce37b3100004f00ab5154?mocky-delay=10000ms") .header("accept", "application/json") diff --git a/spring-boot-bootstrap/pom.xml b/spring-boot-bootstrap/pom.xml index 21c0ea60a8..eb97d6d426 100644 --- a/spring-boot-bootstrap/pom.xml +++ b/spring-boot-bootstrap/pom.xml @@ -79,6 +79,12 @@ test + + javax.servlet + javax.servlet-api + 4.0.0 + + diff --git a/spring-boot-bootstrap/src/main/java/org/baeldung/Application.java b/spring-boot-bootstrap/src/main/java/org/baeldung/Application.java index f7e7bb0347..ba1b444e44 100644 --- a/spring-boot-bootstrap/src/main/java/org/baeldung/Application.java +++ b/spring-boot-bootstrap/src/main/java/org/baeldung/Application.java @@ -3,9 +3,11 @@ package org.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +@ServletComponentScan @SpringBootApplication @ComponentScan("org.baeldung") @EnableJpaRepositories("org.baeldung.persistence.repo") diff --git a/spring-boot-bootstrap/src/main/java/org/baeldung/ForwardedServlet.java b/spring-boot-bootstrap/src/main/java/org/baeldung/ForwardedServlet.java new file mode 100644 index 0000000000..e42da22852 --- /dev/null +++ b/spring-boot-bootstrap/src/main/java/org/baeldung/ForwardedServlet.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +@WebServlet("/forwarded") +public class ForwardedServlet extends HttpServlet { + + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + PrintWriter out = resp.getWriter(); + out.write("In forwarded servlet page."); + out.write("\nWelcome:" + req.getParameter("name")); + } + +} diff --git a/spring-boot-bootstrap/src/main/java/org/baeldung/HelloServlet.java b/spring-boot-bootstrap/src/main/java/org/baeldung/HelloServlet.java new file mode 100644 index 0000000000..63673143d6 --- /dev/null +++ b/spring-boot-bootstrap/src/main/java/org/baeldung/HelloServlet.java @@ -0,0 +1,19 @@ +package org.baeldung; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@WebServlet("/hello") +public class HelloServlet extends HttpServlet { + + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + RequestDispatcher dispatcher = req.getRequestDispatcher("/forwarded"); + dispatcher.forward(req, resp); + } + +} diff --git a/spring-boot-bootstrap/src/main/java/org/baeldung/RedirectedServlet.java b/spring-boot-bootstrap/src/main/java/org/baeldung/RedirectedServlet.java new file mode 100644 index 0000000000..6d4b1ebce9 --- /dev/null +++ b/spring-boot-bootstrap/src/main/java/org/baeldung/RedirectedServlet.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +@WebServlet("/redirected") +public class RedirectedServlet extends HttpServlet { + + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + PrintWriter out = resp.getWriter(); + out.write("In redirected servlet page."); + out.write("\nWelcome:" + req.getParameter("name")); + } + +} diff --git a/spring-boot-bootstrap/src/main/java/org/baeldung/WelcomeServlet.java b/spring-boot-bootstrap/src/main/java/org/baeldung/WelcomeServlet.java new file mode 100644 index 0000000000..b4a51fc4dc --- /dev/null +++ b/spring-boot-bootstrap/src/main/java/org/baeldung/WelcomeServlet.java @@ -0,0 +1,18 @@ +package org.baeldung; + + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@WebServlet("/welcome") +public class WelcomeServlet extends HttpServlet { + + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.sendRedirect(req.getContextPath() + "/redirected"); + } + +} diff --git a/spring-boot-bootstrap/src/test/java/org/baeldung/HelloServletTest.java b/spring-boot-bootstrap/src/test/java/org/baeldung/HelloServletTest.java new file mode 100644 index 0000000000..93e52cf0be --- /dev/null +++ b/spring-boot-bootstrap/src/test/java/org/baeldung/HelloServletTest.java @@ -0,0 +1,25 @@ +package org.baeldung; + +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import javax.servlet.ServletException; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class HelloServletTest { + @Test + public void whenRequested_thenForwardToCorrectUrl() throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello"); + request.addParameter("name", "Dennis"); + MockHttpServletResponse response = new MockHttpServletResponse(); + HelloServlet servlet = new HelloServlet(); + + servlet.doGet(request, response); + + assertEquals("/forwarded", response.getForwardedUrl()); + assertEquals(200, response.getStatus()); + } +} diff --git a/spring-boot-bootstrap/src/test/java/org/baeldung/WelcomeServletTest.java b/spring-boot-bootstrap/src/test/java/org/baeldung/WelcomeServletTest.java new file mode 100644 index 0000000000..a52b2a5c01 --- /dev/null +++ b/spring-boot-bootstrap/src/test/java/org/baeldung/WelcomeServletTest.java @@ -0,0 +1,25 @@ +package org.baeldung; + +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import javax.servlet.ServletException; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class WelcomeServletTest { + @Test + public void whenRequested_thenRedirectedToCorrectUrl() throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/welcome"); + request.addParameter("name", "Dennis"); + WelcomeServlet servlet = new WelcomeServlet(); + MockHttpServletResponse response = new MockHttpServletResponse(); + + servlet.doGet(request, response); + + assertEquals("/redirected", response.getRedirectedUrl()); + assertEquals(302, response.getStatus()); + } +} diff --git a/spring-core/src/main/java/com/baeldung/lazy/AppConfig.java b/spring-core/src/main/java/com/baeldung/lazy/AppConfig.java new file mode 100644 index 0000000000..0d76876cd8 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/lazy/AppConfig.java @@ -0,0 +1,23 @@ +package com.baeldung.lazy; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; + +@Lazy +@Configuration +@ComponentScan(basePackages = "com.baeldung.lazy") +public class AppConfig { + + @Lazy + @Bean + public Region getRegion(){ + return new Region(); + } + + @Bean + public Country getCountry(){ + return new Country(); + } +} diff --git a/spring-core/src/main/java/com/baeldung/lazy/City.java b/spring-core/src/main/java/com/baeldung/lazy/City.java new file mode 100644 index 0000000000..27073b5fe7 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/lazy/City.java @@ -0,0 +1,13 @@ +package com.baeldung.lazy; + +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +@Lazy +@Component +public class City { + + public City() { + System.out.println("City bean initialized"); + } +} diff --git a/spring-core/src/main/java/com/baeldung/lazy/Country.java b/spring-core/src/main/java/com/baeldung/lazy/Country.java new file mode 100644 index 0000000000..dbac1a2bdc --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/lazy/Country.java @@ -0,0 +1,8 @@ +package com.baeldung.lazy; + +public class Country { + + public Country() { + System.out.println("Country bean initialized"); + } +} diff --git a/spring-core/src/main/java/com/baeldung/lazy/Region.java b/spring-core/src/main/java/com/baeldung/lazy/Region.java new file mode 100644 index 0000000000..5211e5d622 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/lazy/Region.java @@ -0,0 +1,19 @@ +package com.baeldung.lazy; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; + +public class Region { + + @Lazy + @Autowired + private City city; + + public Region() { + System.out.println("Region bean initialized"); + } + + public City getCityInstance() { + return city; + } +} diff --git a/spring-core/src/test/java/com/baeldung/Lazy/LazyAnnotationUnitTest.java b/spring-core/src/test/java/com/baeldung/Lazy/LazyAnnotationUnitTest.java new file mode 100644 index 0000000000..187d573557 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/Lazy/LazyAnnotationUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.Lazy; + +import com.baeldung.lazy.AppConfig; +import com.baeldung.lazy.Country; +import com.baeldung.lazy.Region; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class LazyAnnotationUnitTest { + + @Test + public void givenLazyAnnotation_whenConfigClass_thenLazyAll() { + // Add @Lazy to AppConfig.class while testing + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(AppConfig.class); + ctx.refresh(); + ctx.getBean(Region.class); + ctx.getBean(Country.class); + } + + @Test + public void givenLazyAnnotation_whenAutowire_thenLazyBean() { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(AppConfig.class); + ctx.refresh(); + Region region = ctx.getBean(Region.class); + region.getCityInstance(); + } + + @Test + public void givenLazyAnnotation_whenBeanConfig_thenLazyBean() { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(AppConfig.class); + ctx.refresh(); + ctx.getBean(Region.class); + } +} diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml index 4cefa83442..fc05a6ff16 100644 --- a/spring-jersey/pom.xml +++ b/spring-jersey/pom.xml @@ -15,12 +15,12 @@ - 2.25.1 - 3.0.0 + 2.26 + 3.2.0 1.6.1 - 4.4.5 - 4.5.2 - 3.1.0 + 4.4.9 + 4.5.5 + 4.0.0 @@ -85,7 +85,7 @@ org.glassfish.jersey.ext - jersey-spring3 + jersey-spring4 ${jersey.version} @@ -177,4 +177,4 @@ - \ No newline at end of file +