Saturday, 29 December 2018

Abstract Class in Java

An abstract class in Java is a class that is declared using the abstract keyword. An abstract class may contain methods without any implementation, called abstract methods along with methods with implementations.

The declaration of an abstract method starts with the abstract keyword and ends with a semicolon, it does not have a method body.

General form of abstract method in Java

abstract type method_Name(parameter_list);

If a class contains an abstract method, either declared or inherited from another class, it must be declared as an abstract class.

Note that a class with all its methods implemented can also be declared as abstract. But declaring the class as abstract is mandatory if there is any abstract method in a class.


Usage of Abstract class in Java

There are scenarios when you would want to define a generalized structure using a super class without providing a complete implementation of every method. In that case sub classes have the responsibility to provide implementation for the methods.

In such scenario where base class just provides the general template and the sub-classes provide the specific implementation, base class can be defined as an abstract class with implementation for methods that are common for the sub-classes. Methods for which implementation varies are marked as abstract methods in the base class thus leaving it to the sub-classes to provide implementation for such methods.

Restrictions with Abstract Classes in Java

  • Any class that contains one or more abstract methods must also be declared abstract.
  • Abstract class can not be directly instantiated so there can't be any object of an abstract class.
  • Any class that extends an abstract class must provide implementation of all the abstract methods in the super class; otherwise the sub-class must be declared abstract itself.
  • There can't be an abstract constructor or abstract static method.

Java Abstract class Example

Let's say we have an abstract class Shape which defines the general structure for the 2D figures and declares area method which is abstract. That would mean any sub-class extending the super class Shape has to provide an implementation of meaningful area method.

abstract class Shape{
 double length;
 double breadth;
 //Constructor
 Shape(double length, double breadth){
  this.length = length;
  this.breadth = breadth;
 }
 // common method
 public String getFigureType(){
  return "2D figure";
 }
 // Abstract method
 abstract void area();
}

class Triangle extends Shape{
 //constructor to initialize length
 Triangle(double i, double j){
  super(i, j); // calling the super class constructor  
 }
 // Abstract method implementation for Triangle class
 void area(){
  System.out.println("In area method of Triangle");
  System.out.println("Area of Triangle - " + (length * breadth)/2);
 }
}

class Rectangle extends Shape{
 //constructor to initialize length
 Rectangle(double i, double j){
  super(i, j); 
 }
 // Abstract method implementation for Rectangle class
 void area(){
  System.out.println("In area method of Rectangle");
  System.out.println("Area of Rectangle - " + length * breadth);
 }
}

In the above program you can see that the abstract class Shape provides a generalized structure for the 2D figures. There are two fields with in the Shape class representing 2D figure. These two fields can be used to initialize length and breadth of the figure (in case of Rectangle) or the base and height of the figure (in case of Triangle). Since the abstract class Shape is for 2D figure so method getFigureType() will always return same value "2D figure" for any subclass so it is placed with in the abstract class to be used by all the sub classes.

How area is calculated depends on the figure that is why it is declared as abstract in the Shape class so that the class extending the Shape class can provide the appropriate implementation of the area method.

Java Abstract class and run time polymorphism

As we already know there can't be an object of an abstract class, but abstract class can be used to create object references.

We have also seen that abstract class is deigned to be used as a super class with generalized structure. Since run time polymorphism in Java is implemented through the use of super class reference thus it is obvious that abstract class reference (super class reference) could be used to refer to subclass object.

Example

If we take the same Shape class as used above
abstract class Shape{
 double length;
 double breadth;
 //Constructor
 Shape(double length, double breadth){
  this.length = length;
  this.breadth = breadth;
 }
 // Abstract method
 abstract void area();
 
}

class Triangle extends Shape{
 //constructor to initialize length
 Triangle(double i, double j){
  super(i, j); // calling the super class constructor  
 }
 // Abstract method implementation for Triangle class
 void area(){
  System.out.println("In area method of Triangle");
  System.out.println("Area of Triangle - " + (length * breadth)/2);
 }
}

class Rectangle extends Shape{
 //constructor to initialize length
 Rectangle(double i, double j){
  super(i, j); 
 }
 // Abstract method implementation for Rectangle class
 void area(){
  System.out.println("In area method of Rectangle");
  System.out.println("Area of Rectangle - " + length * breadth);;
 }
}

public class PolymorphicTest {
 public static void main(String[] args){
  // Abstract class reference
  Shape shape;
  Triangle triangle = new Triangle(5, 6); 
  Rectangle rectangle = new Rectangle(7, 5); 
  // shape dynamically bound to the Triangle object
  shape = triangle;
  // area method of the triangle called
  shape.area(); 
   // shape dynamically bound to the Rectangle object
  shape = rectangle;
  // area method of the rectangle called 
  shape.area(); 
 }
}

Output

In area method of Triangle
Area of Triangle - 15.0
In area method of Rectangle
Area of Rectangle - 35.0

It can be seen that a reference of an abstract class is created

Shape shape;

That shape reference refers to the object of Triangle class at run time first and then object of Rectangle class and appropriate area method is called.

Abstract class in Java with interfaces

If a class implements an interface but does not implement all the methods of that interface then that class must be declared as abstract.

public interface MyInterface {
 void method1();
 String method2(String Id);
}
abstract class in Java
Error if all methods of interface are not implemented

But we can declare the class as abstract in that case

public abstract class AbstractClassDemo implements MyInterface {
 public static void main(String[] args) {
  System.out.println();
 }
}

Points to note-

  • There can be a class declared as abstract that provides implementation of all the methods in a class i.e. no abstract method in the class but vice versa is not true, if there is any abstract method in a class then the class must be declared abstract.
  • Abstract class in Java may have some methods with implementation and some methods as abstract.
  • Abstract classes can not be instantiated to create an object.
  • An object reference of an abstract class can be created.
  • If a class implements an interface and does not provide implementation for all the interface methods, it must be declared abstract.

That's all for this topic Abstract class in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related Topics

  1. Difference Between Abstract Class And Interface in Java
  2. Inheritance in Java
  3. Polymorphism in Java
  4. final in Java
  5. Core Java Basics Interview Questions

You may also like -

  1. Marker interface in Java
  2. Type Casting in Java
  3. static block in Java
  4. Creating custom exception class
  5. Multi catch statement in Java 7
  6. How and why to synchronize ArrayList in Java
  7. CyclicBarrier in Java concurrency
  8. Deadlock in Java multi-threading

Friday, 28 December 2018

Best Practices For Exception Handling in Java

If you know about these 5 keywords try, catch, finally, throw and throws and how to use them, you pretty much know what Java exception handling is all about.

But there are also some best practices for exception handling in Java which you should try to follow. That is what this post talks about; the do’s and don'ts of the exception handling in Java.

Java Exception Handling Best Practices

  1. Use Specific Exceptions not Exception or Throwable - It is always better to throw specific exception (specific exception sub-classes) rather than the more generic one (i.e. super class) like Throwable, Exception or RunTimeException.

    By doing that we can provide more information to the user what exactly went wrong, the code is also more readable by giving info about various exceptions it can throw rather than everything gobbled up by Exception or Throwable class.

    We should be specific when catching exceptions too. As Example - For RunTimeExceptions (unchecked exceptions) it is said that we should not catch them as they indicate application code errors. If we catch Exception class directly we also catch RuntimeExceptions as RuntimeException class inherits from Exception.

    Same way if we catch throwable directly that is also wrong -

    try {
    } catch(Throwable t) {
        t.printStackTrace();//Should not do this
    }
    

    Throwable is the superclass of all errors and exceptions in Java. Error is the superclass of all errors which are not meant to be caught by applications. Thus, catching Throwable would essentially mean that Errors such as system exceptions (e.g., OutOfMemoryError, StackOverFlowError) would also get caught. And, the recommended approach is that application should not try and recover from Errors such as these. Thus, Throwable and Error classes should not be caught. Only Exception and its subclasses should be caught.

  2. Throw Early or Fail-Fast - Since an exception stack trace shows the exact sequence of method calls till the point of exception, along with class name, file name and the line number where the exception occurs it becomes very important to throw exception as early as possible.

    Let's see what will happen if we don't do that.

     public class ShowFile {
        public static void main(String[] args) {
            File propFile = new File("");
            try{
                readFile(propFile);
            }catch (FileNotFoundException e){
                e.printStackTrace();
            }catch (EOFException e){
                e.printStackTrace();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        
        private static void readFile(File filename) throws 
         FileNotFoundException, EOFException{
            InputStream in = new FileInputStream(filename);       
        }
    }
     

    StackTrace

    java.io.FileNotFoundException: 
     at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at org.netjs.example.ShowFile.readFile(ShowFile.java:37)
        at org.netjs.example.ShowFile.main(ShowFile.java:18)
    

    In the stack trace it is a little difficult to point out the real origin of exception, seeing the stack trace it looks like problem is in FileInputStream though in reality, problem in the code is that there is no check for space passed as file name.

    Let's see how we should do that.

    public class ShowFile {
        public static void main(String[] args) {
            File propFile = new File("");
            try{
                readFile(propFile);
            } catch (FileNotFoundException e){
                e.printStackTrace();
            } catch (IOException e){
                e.printStackTrace();
            }
        }
        
        private static void readFile(File fileName) throws FileNotFoundException, 
         EOFException, IllegalArgumentException{
            if(fileName == null || fileName.getPath().equals("")){
                throw new IllegalArgumentException("File Name not given");
            }
            InputStream in = new FileInputStream(fileName);  
        }
    }
    

    StackTrace

    Exception in thread "main" java.lang.IllegalArgumentException: File Name not given
     at org.netjs.example.ShowFile.readFile(ShowFile.java:42)
     at org.netjs.example.ShowFile.main(ShowFile.java:18)
    

    It can be seen now with the check for the filename the stack trace gives precise information about the problem.

  3. Catch Late - In case of checked exceptions, it is enforced by Java compiler to either catch the exception or declare it in throws clause. So generally developer tends to catch it and do nothing, except printing stacktrace or put a logger, in order to avoid the compiler error. But that way we are not providing the true information of what exactly happened.

    Lets see an example -

    public class ShowFile {
        public static void main(String[] args) {
            File propFile = new File("");
            readFile(propFile);        
        }
        
        private static void readFile(File fileName) {
            InputStream in = null;
            try {
                in = new FileInputStream(fileName);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                in.read();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }        
        }
    }
    

    Stacktrace

    java.io.FileNotFoundException: 
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at org.netjs.example.ShowFile.readFile(ShowFile.java:41)
        at org.netjs.example.ShowFile.main(ShowFile.java:18)
    Exception in thread "main" java.lang.NullPointerException
        at org.netjs.example.ShowFile.readFile(ShowFile.java:47)
        at org.netjs.example.ShowFile.main(ShowFile.java:18)
    

    Here you can see that instead of declaring the exception in throws clause and catching it at the point where it can be handled, try-catch block is used and the exception is caught using FileNotFoundException. If we see the stack trace it is not providing appropriate and precise information why the exception occurred.

    It is better to catch exception only when it can be handled appropriately. We can use throws clause to declare the exception and put the responsibility of catching them on the caller method. This way exception handling has been passed further up the call chain.

    public class ShowFile {
        public static void main(String[] args) {
            File propFile = new File("");
            try{
                readFile(propFile);
            } catch (FileNotFoundException e){
                e.printStackTrace();
            } catch (IOException e){
                e.printStackTrace();
            }    
        }
        
        private static void readFile(File fileName) throws FileNotFoundException, 
         IOException, IllegalArgumentException{
            if(fileName == null || fileName.getPath().equals("")){
                throw new IllegalArgumentException("File Name not given");
            }                 
            InputStream in = new FileInputStream(fileName);
            in.read();                
        }
    }
    
  4. Do not suppress exceptions - The whole idea of having a checked exception in Java is to give a chance to take some action to recover from the raised exception. So ignoring it by having empty braces in the catch block or just printing the stack trace or logging a checked exception and continue with the code is not a best practice.
     try {
        /* ... */
     } catch( Exception e ) {
     
     }
     
      try {
          /* ... */
      } catch( Exception e ) {
          // The exception thrown is lost
          Logger.info( "some exception occured" ); 
      }
      

    We should always avoid empty catch block that just consumes the exception and doesn't provide any meaningful details of exception for debugging purposes.

  5. Don't lose the original exception - Almost all the exception classes provide a constructor with the cause as parameter.
     public Exception(String message, Throwable cause)
    

    Always use the constructor with cause parameter to keep the original exception.
    As exp. - If some excpetion is thrown and you want to wrap it in a custom exception -

     
    catch (IllegalArgumentException exp) {
       throw new MyCustomException("Exception caught: " + e.getMessage());  //Incorrect way
    }
    

    This destroys the stack trace of the original exception, and is always wrong. The correct way of doing this is:

     
    catch (IllegalArgumentException exp) {
       throw new MyCustomException ("Exception caught: " , exp);  //Correct way
    }
    
  6. Custom Exception as checked Exception or Unchecked Exception - If user can take some action to recover from the expected error then make the custom exception a checked exception. On the other hand if user cannot do anything useful in case of error then make the custom exception as an unchecked exception (i.e. inheriting from RunTimeException).

    Most of the time only function of the custom exceptions is to log an error; in that case it should definitely be an unchecked exception.

  7. Follow Naming Convention for exceptions - When creating your own custom exception follow the already established naming convention for exception classes like always end the class name with Exception like NoSuchMethodExcpetion, MyAppException etc.

    Also try to keep the same type of exceptions in the same hierarchy like IOExcpetion is the base class exception for all the IO related exceptions.

  8. Java exception performance consideration - Exceptions do have an impact on the overall performance of the application so use them judiciously. Don't just throw and catch exceptions, if you can use boolean variable to indicate whether an operation was successful or not they try to return a Boolean variable to a caller program and decide the flow of the code based on the returned Boolean.

    Avoid unnecessary Exception handling by fixing root cause. Also check for null yourself before performing any operation or check the array length yourself rather than relying on ArrayIndexOutOfBoundException.

  9. Document the Exceptions Thrown - Use javadoc @throws to clearly specify the exceptions thrown by the method, it's very helpful when you are providing an interface to other applications to use.
  10. Exceptions should not be used for flow control - Raising and handling exception is an expensive operation and should be used for exceptional conditions only. Using it for flow control hits the overall performance and is a strict no no.
    Always check for array length and null values rather than relying on exception handling to do that.

    As example, always check for the array length in a loop

     
    for (int i=0; i < tempArray.length; i++) {
        // code using the tempArray
    }
    
    Don't rely on try-catch block
     
    try {
            for (int i=0; ; i++) {
              // code using the tempArray
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
         …..
      }
    

    Check for null with in a code -

     
    if(obj != null){
        obj.getValue();
    }
    
    Or
    if(someMap.contains(obj)){
        someMap.get(obj);
    } 
    
    Is a better solution than having a try-catch block to do catch a null pointer exception.
    try{
        Obj.getValue()   
    }catch(RuntimeException exp){
       ....
    }
    
  11. Clean up the resources - If you are using resources like database connections, network connections or IO streams, make sure you clean them up using finally block or using the Java 7 ARM feature.

  12. Logging Exceptions and providing helpful message - We should always log exception messages and while throwing exception provide clear message so that caller will know easily why the exception occurred. Always append values in the exception message if possible.

    As example - If we are writing some code where some specific logic is there for senior citizens (Age greater than or equal to 60) and the method throws InvalidAgeException if age is less than 60.

    In that case if exception is thrown then displaying a message "Exception thrown from method METHOD_NAME" or "Invalid parameter" will not be as helpful as saying "Invalid age exception for " + {age}

    That way whoever is seeing the log can easily figure out what was the parameter given when the exception was thrown.

  13. Log and throw anti-pattern - Logging and throwing the exception with in a catch block is considered an error handling anti-pattern and should be avoided.
    catch (NoSuchFieldException exp) {
       LOG.error("Exception occurred", exp);
       throw exp;
    }
    
    Consider the above example code, doing both logging and throwing will result in multiple log messages in log files, for a single problem in the code. Whoever is going through the log will have to go through multiple logs for the same error rather than at one place in a log.

  14. Preserve loose coupling - One of the best practices for the exception handling is to preserve loose coupling. According to that an implementation specific checked exception should not propagate to another layer. As Example SQL exception from the DataAccessCode (DAO layer) should not propagate to the service (Business) layer. The general practice in that case is to convert database specific SQLException into an unchecked exception and throw it.
    catch(SQLException ex){
        throw new RuntimeException("DB error", ex);
    }
    

That's all for this topic Best Practices for Exception Handling in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Creating Custom Exception Class in Java
  2. final Vs finally Vs finalize in Java
  3. Multi-Catch Statement in Java Exception Handling
  4. Try-With-Resources in Java Exception Handling
  5. Java Exception Handling Interview Questions

You may also like -

  1. fail-fast Vs fail-safe iterator in Java
  2. How HashMap Internally Works in Java
  3. Thread states in Java multithreading
  4. Lambda Expression Examples in Java 8
  5. interface default methods in Java 8
  6. ConcurrentHashMap in Java
  7. ArrayBlockingQueue in Java Concurrency
  8. effectively final in Java 8

Thursday, 27 December 2018

Spring JdbcTemplate Select Query Example

In the post Spring JdbcTemplate Insert, Update And Delete Example I have already discussed how JdbcTemplate can be used for inserting and updating data in the DB. I left behind the part to read from Database using Select query. Purpose for doing that is to discuss in detail the callback part of the JdbcTemplate. This post shows how to use Select query using JdbcTemplate in Spring framework and also talks about the callback methods in detail which shows how you can do resultset to model mapping using RowMapper implementation.

In the post Data access in Spring framework it has been discussed in detail how Spring framework provides templates to manage the fixed part and uses call back to handle the variable part. Fetching data from DB using select query has, as usual, the fixed part like getting connection, cleaning up, handling exception but at the same time Spring framework does need help to map the fetched data to the model. That’s where callback comes into picture.

Technologies used

  • Spring 5.0.4
  • Apache DBCP2
  • MYSQL 5.1.39
  • Java 8
  • Apache Maven 3.3.3

In this Spring JdbcTemplate select query example Apache DBCP is used for providing pooled datasource and MYSQL is used as the back end.


Maven dependencies

If you are using maven then you can provide dependencies in your pom.xml.

With all the dependencies your pom.xml should look something like this -

<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>

  <groupId>org.netjs.prog</groupId>
  <artifactId>maven-spring</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>maven-spring</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version>5.0.4.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    
     <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>
    
    <!-- Spring JDBC Support -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    
   <!-- MySQL Driver -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.39</version>
    </dependency>
    
    <!--  Apache DBCP connection pool -->
    <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-dbcp2</artifactId>
       <version>2.1</version>
    </dependency>
  </dependencies>
</project>

Alternatively you can download the jars and add them to the class path.

Database table for example

For this example I have created a table called employee with the columns id, name and age in the MYSQL DB. Column id is configured as auto increment checked so no need to pass id from your query as DB will provide value for it.

CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

Configuring datasource dependency

First thing is to set up DataSource as a bean. I have used properties file to configure datasource where all the properties are there in the db.properties file.

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value = "${db.driverClassName}" />
    <property name="url" value = "${db.url}" />
    <property name="username" value = "${db.username}" />
    <property name="password" value = "${db.password}" />
    <property name="initialSize" value = "${pool.initialSize}" />
</bean>

Where as db.properties file which is under the config folder has all the properties.

db.properties

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/netjs
db.username=
db.password=
pool.initialSize=5

Description of the properties is as-

driver class name is the JDBC driver for the DB used. Since MYSQL is used here so the jdbc driver for the same (com.mysql.jdbc.Driver) is provided.

Url – You need to provide url to access your DB server. I have created a schema called netjs and DB is running on the same system so url is jdbc:mysql://localhost:3306/netjs.

Username and password for the DB.

IntialSize is the initial size of the connection pool. It is given as 5 so initially 5 connections will be created and stored in the pool.

To use properties file you need to put following configuration in your XML.

<context:property-placeholder location="classpath:config/db.properties" />

Spring JDBCTemplate configuration

DataSource bean has to be provided as a reference in JdbcTemplate.

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
    <property name="dataSource" ref="dataSource"></property>  
</bean>

Java Classes

Since Spring always promotes to use interfaces and there is also a JEE design pattern for database layer called DAO which also says the same thing - Separate low level data access code from the business layers.

So we have a EmployeeDAO interface with find methods and its implementing class EmployeeDAOImpl. There is also a model class Employee with all the getters/setters.

Employee.java class

public class Employee {
 private int empId;
 private String empName;
 private int age;
 
 public int getEmpId() {
  return empId;
 }
 public void setEmpId(int empId) {
  this.empId = empId;
 }
 public String getEmpName() {
  return empName;
 }
 public void setEmpName(String empName) {
  this.empName = empName;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
}

EmployeeDAO interface

import org.netjs.model.Employee;

public interface EmployeeDAO {
    public List<Employee> findAllEmployees();
    
    public Employee findEmployee(int empId);
}

EmployeeDAOImpl class

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.netjs.dao.EmployeeDAO;
import org.netjs.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

@Repository
public class EmployeeDAOImpl implements EmployeeDAO {
    @Autowired
    private JdbcTemplate jdbcTemplate; 
    
    final String SELECT_BY_ID_QUERY = "SELECT id, name, age from EMPLOYEE where id = ?";
    final String SELECT_ALL_QUERY = "SELECT id, name, age from EMPLOYEE";
    
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
        this.jdbcTemplate = jdbcTemplate;  
    }
    
    public Employee findEmployee(int empId) {
        return this.jdbcTemplate.queryForObject(SELECT_BY_ID_QUERY, new EmployeeMapper(), 
        empId);
    }

    public List<Employee> findAllEmployees() {
        return this.jdbcTemplate.query(SELECT_ALL_QUERY, new EmployeeMapper());
    }

    private static final class EmployeeMapper implements RowMapper<Employee> {
        public Employee mapRow(ResultSet rs, int rowNum) throws SQLException         {
            Employee emp = new Employee();
            emp.setEmpId(rs.getInt("id"));
            emp.setEmpName(rs.getString("name"));
            emp.setAge(rs.getInt("age"));
            return emp;
        }
    }
    
}

Notice how you are not writing any code for getting or closing connection, exception handling. All that fixed part is managed by the JdbcTemplate class. Its the JdbcTemplate which is getting the connection using the DataSource provided to it, creating and executing the statement and closing the connection.

If there is any SQLException thrown that is also caught by JdbcTemplate and translated to one of the DataAccessException and rethrown.

Spring RowMapper

Main thing to demonstrate in this Spring JdbcTemplate select query example is how callback works. Here template callbacks are used to query the DB and then map the returned result set to the model (Employee) object(s).

If you have noticed in findEmployee(int empId) method queryForObject method of JdbcTemplate is used which takes 3 parameters-

  • SQL query String
  • RowMapper object that maps a single result row to a Java object via a RowMapper
  • varargs to bind parameters to the query

Whereas in findAllEmployees() method query method is used which takes only two parameters –

  • SQL query String
  • RowMapper object

as there are no parameters to be passed to the SQL so varargs are not needed in this case.

Main thing here is RowMapper object which in this example is the object of class EmployeeMapper implementing the RowMapper interface.
RowMapper interface has a single method mapRow which takes two arguments -

  1. ResultSet - A table of data representing a database result set
  2. int - the number of the current row
and this method returns the result object for the current row.

For every row in the result set, JdbcTemplate calls the mapRow() method of the RowMapper interface implementing class. Arguments passed are ResultSet and an integer which is the number of the current row in the result set. Using that row number cursor is moved to the given row in the result set.

XML Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:component-scan base-package="org.netjs.daoimpl" />
    <!--  For reading properties files --> 
    <context:property-placeholder location="classpath:config/db.properties" />
    
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
        <property name="dataSource" ref="dataSource"></property>  
    </bean>  
    <!-- <bean id="employeeDAO" class="org.netjs.daoimpl.EmployeeDAOImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>  
    </bean> -->
    
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value = "${db.driverClassName}" />
        <property name="url" value = "${db.url}" />
        <property name="username" value = "${db.username}" />
        <property name="password" value = "${db.password}" />
        <property name="initialSize" value = "${pool.initialSize}" />
    </bean>

</beans>

If you are not using component scanning, then you can uncomment the bean definition for the EmployeeDAO.

Test class

You can use the following code in order to test the code -

import java.util.List;
import org.netjs.dao.EmployeeDAO;
import org.netjs.model.Employee;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

    public static void main(String[] args) {
        
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
         ("appcontext.xml");
        EmployeeDAO dao = (EmployeeDAO)context.getBean("employeeDAOImpl");  
        
        // Uncomment this to find employee by ID
        /*Employee emp = dao.findEmployee(5);
        System.out.println("Name - "+ emp.getEmpName() + " Age - " + emp.getAge());*/
        
        List<Employee> empList = dao.findAllEmployees();
        System.out.println("Name - "+ empList.get(1).getEmpName() + " Age - " 
          + empList.get(1).getAge());
    }
}

RowMapper implementation as Lambda Expression

RowMapper interface has only single method mapRow which means it is a functional interface. Starting Java 8 it can be implemented as a lambda expression. Since same implementation is used by two methods findEmployee() and findAllEmployees() so it is better to implement it as a lambda block rather than as an inline lambda.

In that case findEmployee() and findAllEmployees() methods will change like this -

    public Employee findEmployee(int EmpId) {
        return this.jdbcTemplate.queryForObject(SELECT_BY_ID_QUERY, getMap(), EmpId);
    }

    public List<Employee> findAllEmployees() {
        return this.jdbcTemplate.query(SELECT_ALL_QUERY, getMap());
    }
    
    private RowMapper<Employee> getMap(){
        // Lambda block
        RowMapper<Employee> empMap = (rs, rowNum) -> {
            Employee emp = new Employee();
            emp.setEmpId(rs.getInt("id"));
            emp.setEmpName(rs.getString("name"));
            emp.setAge(rs.getInt("age"));
            return emp;
        };
        return empMap;
    }

Here it can be seen that lambda block is implemented inside method getMap(). Here lambda is assigned to a functional interface (RowMapper in this case) variable. It has two arguments rs and rowNum, since it is implementing mapRow() method of the RowMapper class so compiler will infer that rs and rowNum are of type ResultSet and int respectively.

Recommendations for learning

  1. Spring Framework Master Class Course
  2. Spring & Hibernate for Beginners (Includes Spring Boot)
  3. Java In-Depth: Become a Complete Java Engineer!
  4. Complete Python Bootcamp Course
  5. React - The Complete Guide Course

That's all for this topic Spring JdbcTemplate Select Query Example. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Configuring DataSource in Spring Framework
  2. Insert\Update Using NamedParameterJdbcTemplate in Spring Framework
  3. Select Query Using NamedParameterJdbcTemplate in Spring Framework
  4. How to inject prototype scoped bean in singleton bean
  5. Using Spring Profiles to Switch Environment

You may also like -

  1. Spring example program using automatic configuration
  2. Autodiscovery of Bean Using component-scan in Spring
  3. @Resource annotation in Spring autowiring
  4. interface default methods in Java 8
  5. String and thread-safety in Java
  6. Difference between Thread and Process in Java
  7. AtomicInteger in Java Concurrency
  8. BlockingDeque in Java Concurrency

Java String Search Using indexOf(), lastIndexOf() And contains() Methods

There are scenarios when you want to find characters or substrings within a String. For that purpose String class in Java provides accessor methods that return the position within the string of a specific character or substring: indexOf() and lastIndexOf().

  • indexOf()- This method searches forward from the beginning of the string and returns the index within this string of the first occurrence of the specified character/substring. If a character or substring is not found indexOf() returns -1.
  • lastIndexOf()- This method searches backward from the end of the string and returns the index within this string of the last occurrence of the specified character/substring. If a character or substring is not found lastIndexOf() returns -1.

The String class also provides a search method, contains, that returns true if the string contains a particular character sequence. Use this method when you only need to know that the string contains a character sequence, but the precise location isn't important.

indexOf() and lastIndexOf() methods in String

There are various overloaded versions of indexOf() and lastIndexOf() methods.

Java indexOf() method

  • indexOf(int ch)- Returns the index within this string of the first occurrence of the specified character.
  • indexOf(int ch, int fromIndex)- Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.
  • indexOf(String str)- Returns the index within this string of the first occurrence of the specified substring.
  • indexOf(String str, int fromIndex)- Returns the index within this string of the first occurrence of the specified substring, starting at the specified index.

Java lastIndexOf() method

  • lastIndexOf(int ch)- Returns the index within this string of the last occurrence of the specified character.
  • lastIndexOf(int ch, int fromIndex)- Returns the index within this string of the last occurrence of the specified character, searching backward starting at the specified index.
  • lastIndexOf(String str)- Returns the index within this string of the last occurrence of the specified substring.
  • lastIndexOf(String str, int fromIndex)- Returns the index within this string of the last occurrence of the specified substring, searching backward starting at the specified index.

Searching for character in a String using indexOf() and lastIndexOf() methods

  1. If you get date as String in the dd/mm/yyyy format and you want to get the first index of char '/'.
    public class StringSearch {
    
     public static void main(String[] args) {
      String date = "12/01/2016";
      System.out.println("index " + date.indexOf('/'));
     }
    }
    

    Output

    index 2
    
  2. Using the same date string if you want to get the month part of it.
    public class StringSearch {
    
     public static void main(String[] args) {
      String date = "12/01/2016";
      System.out.println("index " + date.indexOf('/'));
      String month = date.substring(0, date.indexOf('/'));
      System.out.println("month " + month);
     }
    }
    

    Output

    index 2
    month 12
    
  3. Using the same date string if you want to get the year part then you can use lastIndexOf() method.
    public class StringSearch {
    
     public static void main(String[] args) {
      String date = "12/01/2016";
      System.out.println("index " + date.lastIndexOf('/'));
      String year = date.substring(date.lastIndexOf('/') + 1);
      System.out.println("year " + year);
     }
    }
    

    Output

    index 5
    year 2016
    
  4. If you get some string in the format “xx/xx/xx” and you want the middle substring.
    public class StringSearch {
    
     public static void main(String[] args) {
      String path = "home/index/test.html";
      
      String str = path.substring(path.indexOf('/') + 1, path.lastIndexOf('/'));
      System.out.println("str - " + str);
    
     }
    }
    

    Output

    str - index
    

Searching for substring in a String using indexOf() and lastIndexOf() methods

Same way you can also use indexOf() and lastIndexOf() methods to search for a substring within a given string.

public class StringSearch {
 public static void main(String[] args) {
     String str = "This is a test String to test searching in String";
     System.out.println("First occurrence of String test is at index- "
               + str.indexOf("test"));
     System.out.println("Last occurrence of String test is at index- " 
               + str.lastIndexOf("test"));
     System.out.println("Content between fist and last occurrence of test in the String- " 
               + str.substring(str.indexOf("test"), str.lastIndexOf("test")));
       
     System.out.println("First occurrence of String test after index 15- " 
               + str.indexOf("test", 15));
 }
}

Output

First occurrence of String test is at index- 10
Last occurrence of String test is at index- 25
Content between fist and last occurrence of test in the String- test String to 
First occurrence of String test after index 15- 25

Searching in String using contains() method

public boolean contains(CharSequence s) - Returns true if and only if this string contains the specified sequence of char values. Otherwise it returns false.

Java contains() method example

public class StringSearch {

 public static void main(String[] args) {
  String str1 = "Contains example";
  String str2 = "example";
  System.out.println("str1 contains str2 " + str1.contains(str2));
 }
}

Output

str1 contains str2 true

Here note that str2 which is passed as an argument in contains() method is a string not CharSequence, so string can be used in place of CharSequence. It is possible because CharSequence is an interface which is implemented by String.

If you want to use contains() method ignoring case then you can convert both strings to upper or lowercase while searching.

As example – In previous program if str2 is changed to “Example” then contains will return false.

public class StringSearch {
 public static void main(String[] args) {
  String str1 = "Contains example";
  String str2 = "Example";
  System.out.println("str1 contains str2 " + str1.contains(str2));
 }
}

Output

str1 contains str2 false

Now, if you want to ignore case then you can change both to lower case.

public class StringSearch {

 public static void main(String[] args) {
  String str1 = "Contains example";
  String str2 = "Example";
  System.out.println("str1 contains str2 " + str1.toLowerCase().contains(
   str2.toLowerCase()));
 }

}
str1 contains str2 true

It won't change the original strings as strings are immutable and using methods like toLowerCase will create a new string.

That's all for this topic Java String Search Using indexOf(), lastIndexOf() And contains() Methods. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related topics

  1. String Comparison in Java
  2. String charAt() And substring() Methods in Java
  3. String And Thread-Safety in Java
  4. Splitting a String Using split() Method in Java
  5. Java String Interview Questions

You may also like -

  1. How to find all the permutations of the given String
  2. Overriding hashCode() and equals() method in Java
  3. fail-fast Vs fail-safe iterator in Java
  4. Method reference in Java 8
  5. Abstraction in Java
  6. Difference Between equals() Method And equality Operator == in Java
  7. static Block in Java
  8. Difference between component-scan and annotation-config in Spring

Wednesday, 26 December 2018

Wiring Collections in Spring

In the post dependency injection in spring you would have seen examples of configuring both property values and reference to other beans. But these attributes property and ref can only be used with single fields. If you want to wire collections then Spring provides four options List, Set, Map and Props.


Options to wire collections in Spring

  • <list>- Used to wire a list of values in Spring, works with properties of any type of java.util.Collection and also arrays. As in Java list attribute allows duplicates, order is maintained.
  • <set>- Same as list with couple of differences - doesn’t allow duplicates, insertion order not maintained.
  • <map>- Used to wire a collection of (key, value) pair in Spring. Both key and value can be of any type.
  • <props>- Used to wire a collection of (key, value) pair. Both key and value have to be Strings.

Wiring List and Set in Spring example

Order class

Java class which has both List and Set fields.

import java.util.List;
import java.util.Set;

public class Order {
    private String id;
    private List<String> itemList;
    private Set<String> itemSet;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public List<String> getItemList() {
        return itemList;
    }
    public void setItemList(List<String> itemList) {
        this.itemList = itemList;
    }
    public Set<String> getItemSet() {
        return itemSet;
    }
    public void setItemSet(Set<String> itemSet) {
        this.itemSet = itemSet;
    }   
}

XML Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    
    <bean id="orderBean" class="org.netjs.prog.Order">
        <property name="id" value = "1" />
        <property name="itemList">
            <list>
                <value>Laptop</value>
                <value>RAM</value>
                <value>Drive</value>
                <value>Drive</value>
            </list>
        </property>
        <property name="itemSet">
            <set>
                <value>Laptop</value>
                <value>RAM</value>
                <value>Drive</value>
                <value>Drive</value>
            </set>
            
        </property>
    </bean>

</beans>

You can run it using the following Java program -

import java.util.List;
import java.util.Set;
import org.netjs.prog.Order;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
            ("appcontext.xml");
       
        Order orderBean = (Order) context.getBean("orderBean");
        List<String> itemList = orderBean.getItemList();
        for(String item : itemList){
            System.out.println("item from List - " + item);
        }
        
        Set<String> itemSet = orderBean.getItemSet();
        for(String item : itemSet){
            System.out.println("item from set - " + item);
        }
    }
}

Output

creating instance of class Admin
creating instance of class Admin
item from List - Laptop
item from List - RAM
item from List - Drive
item from List - Drive
item from set - Laptop
item from set - RAM
item from set - Drive

Here it can be noted that Set has not stored duplicate value.

As mentioned above, List and Set can wire any type of java.util.Collection and also arrays, you can check it by changing the List and Set in Order class respectively to -

private String[] itemList;
private Collection<String> itemSet

without changing anything in XML configuration and it will work just fine.

Bean reference with List and Set

You can reference another bean too while wiring a List or Set.
Let's say we have two classes Order and Item.

Order class

import java.util.List;
import java.util.Set;

public class Order {
    private String id;
    private List<Item> itemList;
    private Set<Item> itemSet;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public List<Item> getItemList() {
        return itemList;
    }
    public void setItemList(List<Item> itemList) {
        this.itemList = itemList;
    }
    public Set<Item> getItemSet() {
        return itemSet;
    }
    public void setItemSet(Set<Item> itemSet) {
        this.itemSet = itemSet;
    }    
}

Item Class

public class Item {
    private String name;
    private double price;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }  
}

XML Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">

    <bean id="itemBean" class="org.netjs.prog.Item" >
        <property name="name" value = "Laptop" />
        <property name="price" value = "300.45" />
    </bean>
    <bean id="orderBean" class="org.netjs.prog.Order">
        <property name="id" value = "1" />
        <property name="itemList">
            <list>
                <ref bean="itemBean" />
                <bean class="org.netjs.prog.Item">
                    <property name="name" value = "RAM" />
                    <property name="price" value = "34.78" />
                </bean>
            </list>
        </property>
        <property name="itemSet">
            <set>
                <ref bean="itemBean" />
                <bean class="org.netjs.prog.Item">
                    <property name="name" value = "Drive" />
                    <property name="price" value = "50.67" />
                </bean>
            </set>
            
        </property>
    </bean>

</beans>

Note here in Configuration there are two ways to refer another bean, you can either give a reference using ref attribute or within a list attribute you can define a bean.

You can run this using the following Java program -

import org.netjs.prog.Item;
import org.netjs.prog.Order;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
          ("appcontext.xml");
       
        Order orderBean = (Order) context.getBean("orderBean");
        List<Item> itemList = orderBean.getItemList();
        for(Item item : itemList){
            System.out.println("item from List - " + item.getName() + 
              " " + item.getPrice());
        }
        
        Set<Item> itemSet = orderBean.getItemSet();
        for(Item item : itemSet){
            System.out.println("item from set - " + item.getName() + " " + item.getPrice());
        }
    }
}

Output

creating instance of class Admin
creating instance of class Admin
item from List - Laptop 300.45
item from List - RAM 34.78
item from set - Laptop 300.45
item from set - Drive 50.67

Wiring Map and properties in Spring framework

With Map Key and Value can be String or any other type so there are four options altogether, two for key and two for value.

  • key - Specifies the key of the map entry as a String
  • key-ref - Specifies the key of the map entry as a reference to another bean.
  • value - Specifies the value of the map entry as a String
  • value-ref - Specifies the value of the map entry as a reference to another bean.

With properties both key and value have to be String.

Example Code

Order class

 
import java.util.Map;
import java.util.Properties;

public class Order {
    private String id;
    private Map<String, Item> itemMap;
    private Properties itemProp;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public Map<String, Item> getItemMap() {
        return itemMap;
    }
    public void setItemMap(Map<String, Item> itemMap) {
        this.itemMap = itemMap;
    }
    public Properties getItemProp() {
        return itemProp;
    }
    public void setItemProp(Properties itemProp) {
        this.itemProp = itemProp;
    }    
}

Item Class

 
public class Item {
 private String name;
 private double price;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public double getPrice() {
  return price;
 }
 public void setPrice(double price) {
  this.price = price;
 } 
}

XML Configuration

 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    
    <bean id="itemBean" class="org.netjs.prog.Item" >
        <property name="name" value = "Laptop" />
        <property name="price" value = "300.45" />
    </bean>
    <bean id="orderBean" class="org.netjs.prog.Order">
        <property name="id" value = "1" />
        <property name="itemMap">
            <map>
                <entry key="1" value-ref="itemBean" />
                <entry key="2">
                    <bean class="org.netjs.prog.Item">
                        <property name="name" value = "RAM" />
                        <property name="price" value = "34.78" />
                    </bean>
                </entry>
            </map>
        </property>
        <property name="itemProp">
            <props>
                <prop key="Laptop">500</prop>
                <prop key="RAM">56.89</prop>
            </props>
            
        </property>
    </bean>

</beans>

Here note that with Map also reference can be provided using the ref attribute or as inner bean definition.

You can run it using the following Java program -

 
import java.util.Map;
import java.util.Properties;
import org.netjs.prog.Item;
import org.netjs.prog.Order;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
           ("appcontext.xml");
       
        Order orderBean = (Order) context.getBean("orderBean");
        Map<String, Item> itemMap = orderBean.getItemMap();
        for(Map.Entry<String, Item> item : itemMap.entrySet()){
            
            System.out.println("item from Map - " + item.getKey() + " " + 
            item.getValue().getName() + " " +  item.getValue().getPrice());
        }
        Properties itemProp = orderBean.getItemProp();
        System.out.println("items from Properties " + itemProp);
   }
} 

Output

creating instance of class Admin
creating instance of class Admin
item from Map - 1 Laptop 300.45
item from Map - 2 RAM 34.78
items from Properties {Laptop=500, RAM=56.89}

That's all for this topic Wiring Collections in Spring. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Dependency Injection using factory-method in Spring
  2. Autowiring Using XML Configuration in Spring
  3. Autowiring Using Annotations in Spring
  4. Data Access in Spring Framework
  5. Using depends-on Attribute in Spring

You may also like -

  1. Autodiscovery of Bean Using component-scan in Spring
  2. Lazy Initializing Spring Beans
  3. Bean Definition Inheritance in Spring
  4. Internationalization (i18n) Using MessageSource in Spring
  5. Executor and ExecutorService in Java concurrency
  6. Synchronization in Java multithreading
  7. Producer-Consumer Java program using wait notify
  8. How to find the longest palindrome in the given String

Saturday, 22 December 2018

@Resource Annotation in Spring Autowiring

Apart from supporting JSR-330 annotations like @Inject and @Named for autowiring, Spring also supports injection using the JSR-250 @Resource annotation on fields or bean property setter methods.

@Resource annotation in Spring takes a name attribute, and by default Spring interprets that value as the bean name to be injected. In other words, it follows by-name semantics. That's where it differs from other annotations for autowiring like @Autowired and @Inject which are equivalent to autowiring="byType" in autowiring using XML configuration file.

In case no name is provided with @Resource annotation explicitly, the default name is derived from the field name or setter method.

  • In case of a field, it takes the field name;
  • In case of a setter method, it takes the bean property name.

As example, if we take the following class, then bean with name "payment" will be injected into its setter method

public class PayServiceImpl {

 private IPayCash payment;

 @Resource
 public void setPayment(IPayCash payment) {
  this.payment = payment;
 }
}

But there is also default switching with @Resource annotation, if it doesn't find the bean with the same name it will try to match using type. So if you see how it compares with the other two annotations @Autowired and @Inject-

@Autowired and @Inject annotations

  1. Matches by Type
  2. Restricts by Qualifiers
  3. Matches by Name

@Resource annotation in Spring

  1. Matches by Name
  2. Matches by Type
  3. Restricts by Qualifiers (ignored if match is found by name)

So you can see in case of @Autowired and @Inject switch to "byType" happens only after restricting by Qualifier. Whereas with @Resource it switches to byType if it doesn't find the bean by name.

Another difference between these two types of annotation is that @Autowired and @Inject annotations use the 'AutowiredAnnotationBeanPostProcessor' to inject dependencies. Whereas '@Resource' annotation uses the 'CommonAnnotationBeanPostProcessor' to inject dependencies.

Source : http://stackoverflow.com/questions/4093504/resource-vs-autowired

Spring @Resource annotation example

Here we have a class PayServiceImpl which has a field payment of type IPayment which we have to autowire. Also class CashPayment which implements IPayment interface.

PayServiceImpl class

import javax.annotation.Resource;

public class PayServiceImpl {
 
 @Resource(name="cashPaymentBean")
 private IPayment payment;
 
 public void performPayment() {
  payment.executePayment();
 }
 
 public IPayment getPayment() {
  return payment;
 }
 public void setPayment(IPayment payment) {
  this.payment = payment;
 }
}

Here note the @Resource annotation with name attribute on the field payment.

Interface IPayment

public interface IPayment {
 void executePayment();
}

CashPayment class

public class CashPayment implements IPayment{
 public void executePayment() {
  System.out.println("Perform Cash Payment "); 
 }
}

XML configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
  
  <context:annotation-config />    
 
 <!-- defining CashPayment bean -->
  <bean id="cashPaymentBean" class="org.netjs.exp.Spring_Example.CashPayment" />
 
  <!-- Defining PayServiceImpl bean and injecting payment bean -->
  <bean id="payServiceBean" class="org.netjs.exp.Spring_Example.PayServiceImpl" >
  <!--     <property name="payment" ref="cashPaymentBean" /> -->
  </bean>
</beans>

Here note that the CashPayment class bean is defined with the same name "cashPaymentBean" as used in the @Resource annotation. <context:annotation-config /> tag is added which is required for autowired annotation. Also note that ref for cashPaymentBean is no longer required as a property in paymentBean (it is commented in the config).

You can use the following code to run this program -

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App 
{
    public static void main( String[] args ){
         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
          ("appcontext.xml");
         PayServiceImpl bean = (PayServiceImpl) context.getBean("payServiceBean");
         bean.performPayment();
         context.close();
    }
}

Switching to byType using @Resource annotation

As already mentioned @Resource annotation will switch to "byType" if it is not able to match the bean by name. You can test it by removing the "name" attribute from @Resource annotation.

@Resource
private IPayment payment;

In this case autowiring will be tried by looking for the bean named "payment". Since it is not there so it will match by type and the program will still run.

BeanNotOfRequiredTypeException when using @Resource annotation

Since @Resource annotation tries to match by Name and then by type that may result in exception in some scenarios. Let's see an example. Here we have one more interface IPayCash and field payment in class PayServiceImpl is of type IPayCash.

IPayCash interface

public interface IPayCash {
 void executePayment();
}

PayServiceImpl class

import javax.annotation.Resource;

public class PayServiceImpl {
 
 @Resource(name="cashPaymentBean")
 private IPayCash payment;
 
 
 public void performPayment() {
  payment.executePayment();
 }
 
 public IPayCash getPayment() {
  return payment;
 }
 public void setPayment(IPayCash payment) {
  this.payment = payment;
 }
}

XML configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
  
  <context:annotation-config />    
 
 <!-- defining CashPayment bean -->
  <bean id="cashPaymentBean" class="org.netjs.exp.Spring_Example.CashPayment" />
 
  <!-- Defining PayServiceImpl bean and injecting payment bean -->
  <bean id="payServiceBean" class="org.netjs.exp.Spring_Example.PayServiceImpl" >
  <!--     <property name="payment" ref="cashPaymentBean" /> -->
  </bean>
</beans>

If you see here in XML configuration CashPayment bean is defined with id "cashPaymentBean" and in Class PayServiceImpl @Resource annotation also has the same name attribute @Resource(name="cashPaymentBean") so name matching will happen without any problem.

If you have noticed types are different, in XML configuration cashPaymentBean is defined as an instance of CashPayment class which is of type IPayment, whereas in PayServiceImpl payment field is of type IPayCash. Thus at run time, because of type mismatch, "BeanNotOfRequiredTypeException" is thrown.

Output

WARNING: Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'payServiceBean': 
Injection of resource dependencies failed; nested exception is 
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'cashPaymentBean' 
must be of type [org.netjs.exp.Spring_Example.IPayCash], but was actually of type 
[org.netjs.exp.Spring_Example.CashPayment]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:311)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at org.netjs.exp.Spring_Example.App.main(App.java:10)

That's all for this topic @Resource Annotation in Spring Autowiring. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Autowiring Using Annotations in Spring
  2. Autodiscovery of Bean Using component-scan in Spring
  3. Spring Example Program Using Automatic Configuration
  4. Using Conditional Annotation in Spring Framework
  5. BeanPostProcessor in Spring Framework

You may also like -

  1. Bean Definition Inheritance in Spring
  2. Constructor-Based Dependency Injection in Spring
  3. Select Query Using JDBCTemplate in Spring Framework
  4. Lazy Initializing Spring Beans
  5. Lambda expression examples in Java 8
  6. How to find last modified date of a file in Java
  7. interface default methods in Java 8
  8. BlockingQueue in Java Concurrency