Thursday, August 12, 2021

Spring HelloWorld Example in Java using Annotation and Autowiring

Spring framework has gone a couple of releases since I last share the Spring hello world example with XML configuration. In this article, I am going to explain to you how to create a Spring hello world example with Spring 4.2 release and by using Annotation for dependency injection and autowiring. So no more XML files to specify bean dependencies. It's a simple program that shows how you can use the Spring framework to create Services that are loosely coupled. The example will show you the basic concept of dependency injection by creating a simple Java application that greets the user.

It's actually a little bit complex version of a simple Helloworld program but if you need decoupling and in-direction you need to accept some level of complexity. That's the price you need to pay to achieve flexibility in your code.

In this example, I have a GreetingSevice interface that has just one method greet(). This method is supposed to return a greeting of the day like "Good Morning", "Good AfterNoon, "Good Evening" etc.

Then I have a GreetingBot which prints greeting. This class is decoupled from the GreetingService implementation, with Spring Framework wiring everything together. This means you can provide any kind of GreetingService to greet the user you want like "Hi", "Hello", "Howdy", or whatever you like.

This is possible because GreetingBot calls GreetingService.greet() method to print messages. The good thing is that you don't need to inject any dependency, everything is wired by the Spring framework using auto-wiring.

If you are not familiar with auto-wiring, I suggest you check a comprehensive Spring framework course like Spring MasterClass - Beginner to Expert. There are a lot of different options for wiring and this course will show you that in detail.





Java Source files and classes

GreetingService.java

This is our Service interface, which defines a service method, implemented by a Service provider class.

package hello;
 
public interface GreetingService {
  String greet();
}


GreetingBot.java

A class that uses the GreetingService interface to print greetings. In other words, this is the class that greets users but it is dependent on GreetingService for that, and the Spring framework provides that dependency to this class. At runtime, Spring Framework injects an instance of GreetingService to this class, which is then used by the print() method.

package hello;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class GreetingBot {
 
  final private GreetingService service;
 
  @Autowired
  public GreetingBot(GreetingService service) {
    this.service = service;
  }
 
  public void print() {
    System.out.println(this.service.greet());
  }
}


Main.java

This is our application class, this is the class from which the execution of our Java application starts. This class uses earlier classes to build an application. This is the class that is also annotated with @Configuration and @ComponentScan annotations which means it will be used as configuration as well.

If you look at the code, you will find a main() method, the entry point of the Java application. In this method, the first line of code is about ApplicationContext, which represents a Spring container. In this case, I have used AnnotationConfigApplicatoinContext, which is one implementation of this interface and works based upon annotations.

If you see, we don't have any Spring XML config file, so how does the container know about Spring bean? Well, that's where @Bean annotation is used. If you look closely, you will see we have a method called mockGreetingService() which returns a mock implementation of GreetingService implementation, this method is annotated with @Bean annotations and Spring uses this method to inject dependency on GreetingBot class.

When we call the context.getBean() method returns an instance of GreetingBot which is properly configured with a mock implementation for the GreetingService interface. This all happens under the hood and it's completely transparent to Java developers.  Btw, if you are interested to learn more you can see Spring Framework 5: Beginner to Guru to learn more about Spring container and how exactly the Spring framework works.


package hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
 
@Configuration
@ComponentScan
public class Main {
 
  @Bean
  GreetingService mockGreetingService() {
    return new GreetingService() {
      public String greet() {
        return "Good Day!";
      }
    };
  }
 
  public static void main(String[] args) {
    ApplicationContext context = new AnnotationConfigApplicationContext(
        Main.class);
    GreetingBot greeter = context.getBean(GreetingBot.class);
    greeter.print();
  }
}

Output:
Jan 14, 2016 6:30:15 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@a4a63d8: startup date [Thu Jan 14 18:30:15 SGT 2016]; root of context hierarchy
Good Day!


You can see that our program worked fine and it printed "Good Day!" which comes from the mock implementation of the GreetingService interface. In this program, I have used a couple of essential Spring annotations like @Bean, @Configuration, @ComponentScan, and @Component, which may seem alien to many of you.

A bean is nothing but a replacement of bean tag in XML, ComponentScan is a kind of auto-wiring, a Configuration means this class contains bean definitions, and a class annotated with @Component means it will be detected for auto-wiring.

These are just basic stuff but you want to learn more, check out Learn Spring: The Certification Class by Eugen Paraschiv of Baeldung, one of my fellow blogger and spring instructors. It's actually one of the best courses to learn Spring 5 and Spring Boot 2 from scratch, in a guided, code-focused way

Spring HelloWorld Example in Eclipse using Annotation and Autowiring



Required Dependencies (JAR Files)

If you are not using Maven, then you need to put a lot of JAR files in your application's classpath, or if you are using Eclipse then it's build path. Spring Framework includes a number of different modules for different functionality, and this application will only use the core functionality provided in spring-context, which provides core functionality, but just including the spring-context-4.2.1.RELEASE.jar will not be enough.

You will require a few more JAR one by one to satisfy both compile-time and runtime dependency and avoid those dreaded NoClassDefFoundError and ClassNotFoundExceptions.

In short, you will need the following JAR to run this Spring 4.2 HelloWorld Program in Eclipse.
  • spring-context-4.2.1.RELEASE.jar
  • spring-beans-4.2.1.RELEASE.jar
  • spring-core-4.2.1.RELEASE.jar
  • commons-logging-1.0.4.jar
  • spring-aop-4.2.1.RELEASE.jar
  • spring-expression-4.2.1.RELEASE.jar


Yes, that many JARs you will need, but if you use Maven or Gradle then you just need to specify the following dependency into your pom.xml file and

<dependencies>
  <dependency>
     <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.2.4.RELEASE</version>
  </dependency>
</dependencies>
 
 
and for Gradle:

dependencies {
   compile 'org.springframework:spring-context:4.2.4.RELEASE'
}





Error:

It may be possible that when you first run the program you get some error, mainly because your environment would be different than mine (that's where Docker helps, along with the program it also allows you to take the environment needed by that program). I also faced one error while writing this program and I have posted it here just in case if you get the same one

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.springframework.context.support.AbstractApplicationContext.<init>(AbstractApplicationContext.java:158)
at org.springframework.context.support.GenericApplicationContext.<init>(GenericApplicationContext.java:102)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:60)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:82)
at hello.Application.main(Application.java:21)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 5 more

Solution:

1) Add Apache commons-logging framework JAR into your Eclipse build path.


That's all about how to write Spring 4.2 HelloWorld example in Eclipse IDE without using Maven. In this example, we have also used Annotation and Autowiring to get rid of the XML configuration file. We have used AnnotationConfigApplicationContext as a Bean container instead of ClassPathApplicationContext, which scans Spring config files and classpaths to inject the dependency.


Other Java and Spring articles you may like
  • 5 Spring Boot Features Every Java Developer Should Know (features)
  • Top 5 Free Courses to learn Spring and Spring Boot (courses)
  • 5 Course to Master Spring Boot online (courses)
  • 15 Spring Boot Interview Questions for Java Programmers (questions)
  • 10 Things Java Developer should learn(goals)
  • 10 Advanced Spring Boot Courses for Java Developers (courses)
  • 10 Tools Java Developers use in their day-to-day life (tools)
  • 10 Tips to become a better Java developer (tips)
  • 10 Courses to learn Spring Security with OAuth2 (courses)
  • 3 Best Practices Java Programmers can learn from Spring (best practices)
  • 5 courses to learn Spring Boot and Spring Cloud( courses)
  • 3 ways to change Tomcat port in Spring Boot (tutorial)
  • 10 Spring MVC annotations Java developers should learn (annotations)
  • 7 Courses to learn Microservices in Java (courses)
  • 10 Spring Core Annotations Java Developers should learn (annotations)

Thanks for reading this article so far. If you find these Spring Boot annotations useful then please share them with your friends and colleagues. If you have any questions or feedback then please drop a note.

P. S. - If you want to learn Spring and looking for a free online course then you can also check out these free Spring Framework courses from sites like Udemy and Coursera. it's completely free and all you need to do is create an account to enroll in this course.

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.