Saturday, January 2, 2021

Difference Between component-scan And annotation-config in Spring

To understand the difference between <context:annotation-config/> element and <context:component-scan> element in Spring you have to know about two terms-

  • Autowiring of beans
  • Autodiscovery of beans

Autowiring of beans in Spring

When you use only XML configuration for registering your beans and defining dependencies then you need to configure everything manually in your XML.

As Example If you have 2 classes PayServiceImpl and CashPayment where PayServiceImpl uses object of CashPayment class then in your spring configuration you will have something like this -

<?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">
 
 <!-- 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 use autowiring then also you have two options-

In case you use annotations, you need to activate annotations and you have to add <context:annotation-config /> in your XML file.

With that if we take the same example as above the configuration will be like this-

<?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:annotation-config/>  
 
   <bean id="cashPaymentBean" class="org.netjs.prog.CashPayment" />
 
   <!-- Defining PayServiceImpl bean and injecting payment bean -->
   <bean id="paymentBean" class="org.netjs.prog.PayServiceImpl">
      <!-- <property name="payment" ref="cashPaymentBean" /> -->
   </bean> 
</beans>

Note the inclusion of <context:annotation-config /> and exclusion of <property name="payment" ref="cashPaymentBean" /> (it is commented).

You don't need property as the dependency will be injected automatically but you need one more change for that in your PayServiceImpl class. You need to use @Autowired annotation to autowire the payment property.

import org.springframework.beans.factory.annotation.Autowired;
public class PayServiceImpl implements IPayService {
  private IPayment payment;

  public void performPayment() {
    // calling method on Ipayment implementing class
    payment.executePayment();
  }

  public IPayment getPayment() {
    return payment;
  }

  @Autowired
  public void setPayment(IPayment payment) {
    this.payment = payment;
  }
}

Here points to note are-

  • You have to include <context:annotation-config /> in your XML for autowiring using annotation to work.
  • You don't need to manually write the dependencies with property or constructor-arg tag and ref attribute.
  • You still have to define all your beans because <context:annotation-config /> only works on beans registered within the application context. That's where enters the auto discovery of beans.

Autodiscovery of beans using Spring component scan

With autowiring you can simplify your XML configuration to the extent that you don't need to provide the dependencies. But auto-discovery goes one step further and eliminates the need to add the <bean> tag altogether in your xml.

That can be done using <context:component-scan> element and pointing the base package, it configures Spring to automatically discover beans and declare them for you.

This removes the need to use XML to perform bean registration and for most of the classes you don’t need <bean> element to declare and wire beans.

Annotations used for auto-discovery

Using componentscan element is half of the picture, you need to annotate your classes which needs to be auto-discovered with one of these annotations @Component, @Service, @Controller, @Repository

  • @Component- It is a generic stereotype for any Spring-managed component.
  • @Service- More suitable for a class used as a service.
  • @Repository- This annotation is a marker for any class that fulfills the role or stereotype of a repository (also known as Data Access Object or DAO).
  • @Controller- More suitable for a class used in presentation layer as a controller.
  • Any custom annotation that is itself annotated with @Component.

As example if you have 2 classes PayServiceImpl and CashPayment where PayServiceImpl uses object of CashPayment class then you configuration will look like this-

<?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.prog" />  
 
</beans>

PayServiceImpl class

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

@Service
public class PayServiceImpl implements IPayService {
 @Autowired
 private IPayment payment;

 public void performPayment() {
  // calling method on Ipayment implementing class
  payment.executePayment();
 }
 
 public IPayment getPayment() {
  return payment;
 }
 
 public void setPayment(IPayment payment) {
  this.payment = payment;
 }
}

Here note that the class is annotated with @Service annotation, that's how it is made sure that this class is discovered while a component scan is done. Also note that the dependency to the payment is annotated with the annotation @Autowired. That's how Spring will detect and automatically do the dependency injection.

Class CashPayment

import org.springframework.stereotype.Component;

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

<context:component-scan> Vs <context:annotation-config> in Spring

With the examples we have seen it's easy to list out the differences between <context:component-scan> and <context:annotation-config> in Spring framework.

  1. <context:annotation-config> tag scans and activates annotations for already registered beans in Spring's application context. Examples of the annotations this tag looks for are @Autowired, @Resource, @PostConstruct, @PreDestroy.
    <context:component-scan> tag can automatically detect the classes and register the corresponding beans in the Spring's application context along with scanning and activating for the annotations as done using <context:annotation-config>. For registring the beans the annotations this tag looks for are @Component, @Repository, @Service, @Controller
  2. The use of <context:component-scan> implicitly enables the functionality of <context:annotation-config>. There is usually no need to include the <context:annotation-config> element when using <context:component-scan>. So <context:component-scan> will do everything which <context:annotation-config> does and it provides the added functionality of auto-discovery of beans.

That's all for this topic Difference Between component-scan And annotation-config 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. Spring Component Scan to Automatically Discover Beans
  2. Autowiring in Spring Using @Autowired and @Inject Annotations
  3. How to Inject Prototype Scoped Bean into a Singleton Bean in Spring
  4. Bean Scopes in Spring With Examples
  5. Spring Setter Based Dependency Injection

You may also like-

  1. Circular Dependency in Spring Framework
  2. BeanPostProcessor in Spring Framework
  3. Using Conditional Annotation in Spring Framework
  4. Creating a Maven project in Eclipse
  5. Lambda expressions in Java 8
  6. Check if Given String or Number is a Palindrome Java Program
  7. How to Read File From The Last Line in Java
  8. Difference Between ReentrantLock and Synchronized in Java

Friday, January 1, 2021

Difference Between ArrayList And CopyOnWriteArrayList in Java

CopyOnWriteArrayList was added in Java 5 as a thread-safe alternative to ArrayList, which is one of the most used collection along with HashMap. In this post we'll see the differences between the CopyOnWriteArrayList and ArrayList in Java.

ArrayList Vs CopyOnWriteArrayList in Java

  1. First and foremost difference between CopyOnWriteArrayList and ArrayList is of course thread safety. ArrayList is not thread-safe whereas CopyOnWriteArrayList is thread-safe and fit for use in multi-threaded environment.

    This thread safety in CopyOnWriteArrayList is achieved by making a fresh copy of the underlying array with every mutative operations (add, set, and so on).

  2. Iterator returned by ArrayList is fail-fast. Which means, if the underlying collection is structurally modified in any way except through the iterator's own remove or add methods, it will throw ConcurrentModificationException.

    Iterator returned by CopyOnWriteArrayList is fail-safe. Iterators for the CopyOnWriteArrayList uses a reference to the state of the array at the point that the iterator was created. Since any mutation will result in a fresh copy of the underlying array. Thus the array that the iterator has a reference to never changes during the lifetime of the iterator, so interference is impossible and the iterator is guaranteed not to throw ConcurrentModificationException.

    Let's see this difference with an example, here we'll have an ArrayList which will be iterated. Simultaneously a new thread is created which will try to add an element to that ArrayList.

    public class CADemo {
      public static void main(String[] args) {
        List<Integer> numList = new ArrayList<Integer>();
        // Adding 5 elements to the set
        for(int i=1;i<=5;i++) {
          numList.add(i);
        }
            
        // Creating new thread
        new Thread(new Runnable(){
          @Override
          public void run() {
            try {
              // introducing some delay
              Thread.sleep(150);
            } catch (InterruptedException e) {
              Thread.currentThread().interrupt();
            }
            // add new element to the set
            numList.add(6);
            System.out.println("" + numList);
          }
        }).start();
                    
        // get an iterator
        Iterator<Integer> itr = numList.iterator();
        while(itr.hasNext()){
          Integer i = itr.next();
          try {
            Thread.sleep(30);
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
          //itr.remove();
          System.out.println("" + i);
        }
      }
    }
    

    Output

    1
    2
    3
    4
    5
    [6]
    Exception in thread "main" java.util.ConcurrentModificationException
     at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
     at java.util.ArrayList$Itr.next(Unknown Source)
     at org.netjs.prgrm.CADemo.main(CADemo.java:37)
    

    Here it can be seen that the ConcurrentModificationException is thrown as there is an attempt to add an element to the ArrayList while it is iterated.

    Example code with CopyOnWriteArrayList

    Now let's changed the ArrayList with CopyOnWriteArrayList.

    public class CADemo {
      public static void main(String[] args) {
        List<Integer> numList = new CopyOnWriteArrayList<Integer>();
        // Adding 5 elements to the set
        for(int i=1;i<=5;i++) {
          numList.add(i);
        }
            
        // Creating new thread
        new Thread(new Runnable(){
          @Override
          public void run() {
            try {
              // introducing some delay
              Thread.sleep(150);
            } catch (InterruptedException e) {
              Thread.currentThread().interrupt();
            }
            // add new element to the set
            numList.add(6);
            System.out.println("" + numList);
          }
        }).start();
            
            
        // get an iterator
        Iterator<Integer> itr = numList.iterator();
        while(itr.hasNext()){
          Integer i = itr.next();
          try {
            Thread.sleep(30);
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
          //itr.remove();
          System.out.println("" + i);
        }
      }
    }
    

    Output

    1
    2
    3
    4
    [1, 2, 3, 4, 5, 6]
    5
    

    Here it can be seen that the ConcurrentModificationException is not thrown. Also, since iterator gets its own copy so it doesn't reflect the change made to the CopyOnWriteArrayList while iteration is done.

  3. Performance wise ArrayList is faster as it is not synchronized and there is no added burden of thread-safety. CopyOnWriteArrayList is comparatively slower and if there are lots of writes by various threads that will degrade the performance of the CopyOnwriteArrayList as there will be copies made per mutation.

That's all for this topic Difference Between ArrayList And CopyOnWriteArrayList in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Difference Between HashMap And ConcurrentHashMap in Java
  2. Difference Between CountDownLatch And CyclicBarrier in Java
  3. Difference Between ReentrantLock and Synchronized in Java
  4. CopyOnWriteArraySet in Java With Examples
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. How to Loop or Iterate an Arraylist in Java
  2. How to Join Lists in Java
  3. Fail-Fast Vs Fail-Safe Iterator in Java
  4. Java BlockingQueue With Examples
  5. Lambda Expressions in Java 8
  6. Race Condition in Java Multi-Threading
  7. Deadlock in Java Multi-Threading
  8. Java Pass by Value or Pass by Reference

Setting And Getting Thread Name And Thread ID in Java

In a multi-threading application if lots of thread have been spawned and you want to identify those thread then you can get the thread's name or thread's ID. This post shows how to set and get thread's name in Java and how to get thread ID in Java.

Setting Thread's name in Java

If you want to set a thread’s name in order to identify a thread that can be done in 2 ways.

  1. Using the constructor of the Thread class
  2. Using the setName() method

Monday, December 28, 2020

Lazy Initialization in Spring Using lazy-init And @Lazy Annotation

In Spring framework, by default all the singleton beans are eagerly created and configured by ApplicationContext as part of the initialization process. Though this behavior of pre-instantiation is desirable most of the time as you can detect errors in the configuration immediately. But sometimes you may have a large object graph and loading all those beans in the beginning itself may be expensive. In that kind of scenario you can prevent pre-instantiation of a singleton bean by configuring the Spring bean to be initialized lazily.

If you mark a bean as lazy-initialized in Spring that means IoC container will create a bean instance when it is first requested, rather than at startup.

Here note that when a lazy-initialized bean is a dependency of a singleton bean that is not lazy initialized, the ApplicationContext creates the lazy-initialized bean at startup, because it must satisfy the singleton’s dependencies.

Saturday, December 26, 2020

Injecting Inner Beans in Spring

This post shows how to inject inner beans in Spring and what are the scenarios when you would need to inject a bean as an inner bean.

Let’s say you have a Java class which refers to another class object and the access type for that object is private. In that case what do you think is the best way to provide bean definition in Spring. Let me provide class (Employee.java) here so you can understand what I am saying.

Friday, December 25, 2020

ServiceLocatorFactoryBean in Spring Framework

ServiceLocatorFactoryBean in Spring framework as the name suggests is an implementation of service locator design pattern and helps with locating the service at run time.

ServiceLocatorFactoryBean helps if you have more than one implementation of the same type and want to use the appropriate implementation at the run time i.e. you have an interface and more than one class implementing that interface and you want to have a factory that will return an appropriate object at run time.

registerShutdownHook() Method in Spring Framework

In the post Spring Bean Life Cycle we have already seen that you can provide destroy methods for your beans to do clean up. One problem is that these destroy callback methods are not executed automatically you do have to call AbstractApplicationContext.destroy or AbstractApplicationContext.close before shutting down the IOC container. There is another option to ensure graceful shutdown, you can register a shutdown hook with the JVM using registerShutdownHook() method in Spring.

Note that this problem is only with non-web applications. Spring’s web-based ApplicationContext implementations already have code in place to shut down the Spring IoC container gracefully when the relevant web application is shut down.