Tuesday 18 August 2020

How to configure Spring Application using java based configuration


How to configure Spring Application using java based configuration 


Spring Application Require a Config class to define the bean definition .
The config class annotated with @Configuration annotation and @Bean annotation used for bean describe bean definition.

AnnotationConfigApplicationContext  class an implementation of ApplicationContext is used to 

initialization of  Spring application config using spring configuration class 

SpringConfig .java

package in.jk.javaconfig;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringConfig {

@Bean(name = "user")
public User getUser() {
return new User();

}

}

User .java

package in.jk.javaconfig;

public class User {

private int userId;
private String userName;
private String password;
private String email;

public int getUserId() {
return userId;
}

public void setUserId(int userId) {
this.userId = userId;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

@Override
public String toString() {
return "User [userId=" + userId + ", userName=" + userName + ", password=" + password + ", email=" + email
+ "]";
}

}

SpringApplication .java

package in.jk.javaconfig;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringApplication {

public static void main(String[] args) {

ApplicationContext applicationContext =  null;
               applicationContext =new AnnotationConfigApplicationContext(SpringConfig.class);
System.out.println("Spring Config initialize :: ");
User user = (User) applicationContext.getBean("user");

user.setUserId(1);
user.setUserName("jk");
user.setEmail("jk@gmail.com");
user.setPassword("jk123");
System.out.println(user);

}

}


Here is output in console -

Spring Config initialize :: 
User [userId=1, userName=jk, password=jk123, email=jk@gmail.com]



How HashMap Works in Java

How HashMap Works in Java 


HashMap is a class in Java as a part of collection framework . HashMap used to store object in  the form of key value pair .

where key and value both are objects. 

To store a object in HashMap it have following method 

public V put(K key V Value){}

To store a Object we have to create an object of HashMap class when we do this it create a array  .
each object strorage location in the array called bucket and in order to store object at bucket location.

in HashMap use hashcode of key object which is calculated by hashing .

hashcode value generated by hash function of key object also use provide name of bucket in which object store .
  
as we know two different object can have same hashcode in that situation same hashcode bucket location  contain a LinkList 

in that list HashMap store all same hashcode objects .

To get the value from HashMap 


To get an object from HashMap require key name of Object and use following get method

public V get(K key)

The Get method first calculate the hashcode of key object to find out the bucket address for getting object from bucket

if more the one object found for same hashcode in particuler bucket location in  the LinkList

equals method use for key object to checked the equality of object with stored object key if it return true then 
the corresponding object is return by get method .


How to Override equals and hashcode method

How to Override equals and hashcode method 

equals method: equals is a method  check equality of two object based on content of object 

if two object have same data then it return true otherwise it return false.

hashcode method: hashcode method return an integer value which represent memory location of object it can same for two unequal object . but is good practice have different value for each object .


Need of Override the equals and hashcode method 
 
If not overriding the equlas and hashcode method then we can not have or 
store non duplicate object in HashSet or we can't  use our class object as a key in HashMap 



Here is the contract, from the java.lang.Object specialization:

1.Whenever it(hashcode) is invoked on the same object more than once during an execution of a Java application, 
  the hashCode method must consistently return the same integer, provided no information used in equals 
  comparisons on the object is modified. This integer need not remain consistent from one execution of 
  an application to another execution of the same application.
2.If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the 
  two objects must produce the same integer result.

3.It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling 
  the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be 
  aware that producing distinct integer results for unequal objects may improve the performance of hashtables.


Employee  class with overridden equlas and hashcode method 

package in.jk.example;

public class Employee {
private int empId;
private String name;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// Override of hashcode
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.empId;
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
return result;
}
// Override of equlas
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee employee = (Employee) obj;
if (this.empId != employee.empId)
return false;
if (this.name == null) {
if (employee.name != null)
return false;
} else if (!this.name.equals(employee.name))
return false;
return true;
}
@Override
public String toString() {
return "Employee [empId=" + empId + ", name=" + name + "]";
}

}



package in.jk.example;

import java.util.HashSet;

public class Application {

public static void main(String[] args) {

Employee emp1 = new Employee();
emp1.setEmpId(1);
emp1.setName("JK");

Employee emp2 = new Employee();
emp2.setEmpId(1);
emp2.setName("JK");

Employee emp3 = new Employee();
emp3.setEmpId(1);
emp3.setName("JK");

Employee emp4 = new Employee();
emp4.setEmpId(2);
emp4.setName("jk");

Employee emp5 = new Employee();
emp5.setEmpId(4);
emp5.setName("johny");

Employee emp6 = new Employee();
emp6.setEmpId(4);
emp6.setName("johny");

Employee emp7 = new Employee();
emp7.setEmpId(5);
emp7.setName("johny kumar");

Employee emp8 = new Employee();
emp8.setEmpId(8);
emp8.setName("john");

HashSet<Employee> employees = new HashSet<Employee>();

employees.add(emp1);
employees.add(emp2);
employees.add(emp3);
employees.add(emp4);
employees.add(emp5);
employees.add(emp6);
employees.add(emp7);
employees.add(emp8);

System.out.println("Size : "+employees.size());
employees.stream().forEach(System.out::println);

}

}












How @Qualifier and @Primary Annotation works in Spring

How @Qualifier and @Primary Annotation works in Spring


@Qualifier and @Primary Annotation both used in auto wiring of beans


@Primary Annotation

@Primary Annotation is used to mark a spring as  default primary bean for injection candidate if  container one more bean candidate for a injection bean location.

@Qualifier  Annotation

@Qualifier  Annotation allow to identify a particular bean when more the one bean implementation found for auto wiring during  resolution time of bean object injection  by spring container .

Following code example illustrate the working these annotation 
 
Employee.java

package in.jk.spring.autowired.test;

public interface Employee {

public String toString();

}

Developer.java

package in.jk.spring.autowired.test;

public class Developer implements Employee {

@Override
public String toString() {
return "Developer Bean";
}

}

DeveloperQualifier.java
package in.jk.spring.autowired.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.beans.factory.annotation.Qualifier;

@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface DeveloperQualifier {

}


Manager.java
package in.jk.spring.autowired.test;

public class Manager implements Employee {

@Override
public String toString() {
return "Manager Bean";
}

}

ManagerQualifier.java

package in.jk.spring.autowired.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.beans.factory.annotation.Qualifier;

@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface ManagerQualifier {

}

BeanConfiguration.java

package in.jk.spring.autowired.test;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
public class SpringConfig {

@Bean
@Primary
@DeveloperQualifier()
public Employee getJavaEmp() {
return new Developer();

}

@Bean
@ManagerQualifier()
public Employee getManeger() {
return new Manager();

}

}



TestBean.java

package in.jk.spring.autowired.test;

import org.springframework.beans.factory.annotation.Autowired;

public class TestBean {

@Autowired
@DeveloperQualifier()
Employee developer;

@Autowired
@ManagerQualifier
Employee manager;

public void printEmpoyee() {

System.out.println(developer);
System.out.println(manager);

}

}

SpringApplication.java

package in.jk.spring.autowired.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringApplication {

public static void main(String[] args) {

ApplicationContext applicationContext = null;
applicationContext =new ClassPathXmlApplicationContext("context.xml");

SpringConfig configuration = (SpringConfig ) applicationContext.getBean("config");

TestBean testBean = (TestBean) applicationContext.getBean("testBean");

testBean.printEmpoyee();

}

}



context.xml

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

<context:annotation-config />
<context:component-scan
base-package="in.jk.spring.config" />
<context:property-placeholder
location="classpath:application.properties" />

<bean id="testBean" class="in.jk.spring.autowired.test.TestBean">

</bean>

<bean id="config"
class="in.jk.spring.autowired.test.SpringConfig ">

</bean>

</beans>