Sunday, August 19, 2018

@Import Annotation in Spring JavaConfig

If you are using JavaConfig in Spring to configure the bean definitions then, in order to modularize your configurations you can use @Import annotation in Spring.

@Import annotation in Spring JavaConfig allows for loading @Bean definitions from another configuration class so you can group your configuration by modules or functionality which makes your code easy to maintain.

@Import annotation is similar to <import/> element which is used to divide the large Spring XML configuration file into smaller XMLs and then import those resources.

How does Spring @Import annotation work

Let’s say you have two configuration classes ConfigA and ConfigB then you can import ConfigA into ConfigB as shown below.

@Configuration
public class ConfigA {
 @Bean
 public A a() {
  return new A();
 }
}

@Configuration
@Import(ConfigA.class)
public class ConfigB {
 @Bean
 public B b() {
  return new B();
 }
}
Then you don’t need to specify both ConfigA.class and ConfigB.class when instantiating the context, so this is not required.
ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigA.class, ConfigB.class);
As bean definitions of ConfigA are already loaded by using @Import annotation with ConfigB bean, only ConfigB needs to be specified explicitly.
ApplicationContext ctx = new AnnotationConfigApplicationContext( ConfigB.class);

Spring @Import annotation example

Let’s see a proper example using @Import annotation and Spring JavaConfig. The objective is to insert a record into DB using NamedParameterJDBCTemplate. For that you need a DataSource, NamedParameterJDBCTemplate configured with that DataSource and a Class where NamedParameterJDBCTemplate is used to insert a record in DB. We’ll use separate config classes in order to have a modular code.

DataSource Configuration

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource(value="classpath:config/db.properties", ignoreResourceNotFound=true)
@Import({EmpConfig.class, JDBCConfig.class})
public class DBConfig {
 @Autowired
 private Environment env;
 
 @Bean
 public BasicDataSource dataSource() {
  BasicDataSource ds = new BasicDataSource();
  System.out.println("User " + env.getProperty("db.username"));
  ds.setDriverClassName(env.getProperty("db.driverClassName"));
  ds.setUrl(env.getProperty("db.url"));
  ds.setUsername(env.getProperty("db.username"));
  ds.setPassword(env.getProperty("db.password"));
  return ds;
 }
}

Here note that DB properties are read from a properties file in Spring. DataSource used is Apache BasicDataSource.

You can see that EmpConfig.class and JDBCConfig.class are imported with in DBConfig class using @Import annotation.

NamedParameterJDBCTemplate configuration

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

public class JDBCConfig {
 private final BasicDataSource dataSource;
   
 @Autowired
 public JDBCConfig(BasicDataSource dataSource) {
  this.dataSource = dataSource;
 }
 
 @Bean
 public NamedParameterJdbcTemplate namedJdbcTemplate() {
  return new NamedParameterJdbcTemplate(dataSource);
 }
}

EmpConfig Class

import org.netjs.dao.EmployeeDAO;
import org.netjs.daoimpl.EmployeeDAOImpl1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

public class EmpConfig {
 
 @Autowired
 private NamedParameterJdbcTemplate namedJdbcTemplate;
 @Bean
 public EmployeeDAO empService() {
  return new EmployeeDAOImpl(namedJdbcTemplate);
 }
}

EmployeeDAO class

public interface EmployeeDAO {
 public int save(Employee employee);
  
}

EmployeeDAOImpl class

public class EmployeeDAOImpl1 implements EmployeeDAO {
    
    private NamedParameterJdbcTemplate namedJdbcTemplate;  
    final String INSERT_QUERY = "insert into employee (name, age) values (:name, :age)";
    
    public EmployeeDAOImpl1(NamedParameterJdbcTemplate namedJdbcTemplate){
        this.namedJdbcTemplate = namedJdbcTemplate;
    }

    @Override
    public int save(Employee employee) {
        // Creating map with all required params
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("name", employee.getEmpName());
        paramMap.put("age", employee.getAge());
        // Passing map containing named params
        return namedJdbcTemplate.update(INSERT_QUERY, paramMap);  
    }
}

Employee Bean

public class Employee {
 private int empId;
 private String empName;
 private int age;
 
 public void setEmpId(int empId) {
  this.empId = empId;
 }

 public void setEmpName(String empName) {
  this.empName = empName;
 }

 public void setAge(int age) {
  this.age = age;
 }
 
 public int getEmpId() {
  return empId;
 }
 
 public String getEmpName() {
  return empName;
 }
 
 public int getAge() {
  return age;
 }
}
You can run this example using the following code.
public class App {

 public static void main(String[] args) { 
   AbstractApplicationContext context = new AnnotationConfigApplicationContext(DBConfig.class);
   EmployeeDAO empBean = (EmployeeDAO)context.getBean("empService");
   Employee emp = new Employee();
   emp.setEmpName("Jacko");
   emp.setAge(27);
   int status = empBean.save(emp);  
   context.close();
 }
}
As you can see only DBConfig.class is specified here not all the three config classes, still you can get empService bean which is defined in EmpConfig.

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

>>>Return to Spring Tutorial Page


Related Topics

  1. Using Conditional Annotation in Spring Framework
  2. @Resource Annotation in Spring Autowiring
  3. @Required Annotation in Spring Framework
  4. Benefits, Disadvantages And Limitations of Autowiring in Spring
  5. Using depends-on Attribute in Spring

You may also like-

  1. Spring Bean Life Cycle
  2. Using Spring Profiles to Switch Environment
  3. Difference Between component-scan And annotation-config in Spring
  4. How ArrayList Works Internally in Java
  5. Difference Between Comparable and Comparator
  6. CopyOnWriteArraySet in Java Concurrency
  7. Count Total Number of Times Each Character Appears in a String - Java Program
  8. What is SafeMode in Hadoop

No comments:

Post a Comment