Saturday, September 4, 2021

BeanFactoryAware Interface in Spring Framework

If a class implements org.springframework.beans.factory.BeanFactoryAware interface, then the class bean is provided with a reference to their owning BeanFactory. BeanFactoryAware interface has a single method setBeanFactory(BeanFactory beanFactory).

BeanFactoryAware interface in Spring

public interface BeanFactoryAware extends Aware {
  void setBeanFactory(BeanFactory beanFactory) throws BeansException
}

As you see there is one callback method setBeanFactory that supplies the owning factory to a bean instance.

Bean implementing BeanFactoryAware interface can look up collaborating beans via the factory (Dependency Lookup). However, in general you should not use it, because it couples the code to Spring and does not follow the Inversion of Control style, where most beans will choose to receive references to collaborating beans via corresponding bean properties or constructor arguments i.e. Dependency Injection.

Spring BeanFactoryAware interface example

As already stated this interface should not be used but one scenario where it can help is having many beans of the same type and deciding at the run time which specific bean to use.

For example– Suppose you have IPayment interface and two implementing classes CardPayment and CashPayment. Based on the user’s choice appropriate bean should be called to execute payments. In this scenario you can use BeanFactoryAware interface to do a dependency lookup and load the required bean.

Let’s see Java code for all the classes.

IPayment interface

public interface IPayment{
 void executePayment();
}

CardPayment.java

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

CashPayment.java

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

IPayService interface

public interface IPayService{
 void performPayment(String paymentType);
}

Class implementing BeanFactoryAware interface

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

public class PayServiceImpl implements IPayService, BeanFactoryAware{
 
 private BeanFactory beanFactory;
 private IPayment payment;
 //private int amount;
 
 public void performPayment(String paymentType) {
  System.out.println("performPayment Method called");
  payment = (IPayment)beanFactory.getBean(paymentType);
  payment.executePayment();
 }
 
 @Override
 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
  this.beanFactory = beanFactory;
 }
}

In the class you can see setBeanFactory() method is implemented, also notice the performPayment() method where the beanFactory is used to load the required bean based on the paymentType parameter.

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">
    
    <bean id="cash" class="org.netjs.exp.Spring_Example.CashPayment" />
    <bean id="card" class="org.netjs.exp.Spring_Example.CardPayment" />
   
    <bean id="payServiceBean" class="org.netjs.exp.Spring_Example.PayServiceImpl">
    </bean>
  
</beans>

Here you can see that there is no bean injected as dependency in the bean definition of payServiceBean. As you are going to get the bean by dependency lookup in performPayment() method.

You can use the following class to run and test the code.

public class App {
  public static void main( String[] args ){
    AbstractApplicationContext context = new ClassPathXmlApplicationContext
       ("appcontext.xml");

    IPayService payBean = (IPayService)context.getBean("payServiceBean");
   
    payBean.performPayment("cash");
   
    payBean.performPayment("card");

    context.registerShutdownHook(); 
  }  
}

Output

performPayment Method called
Perform Cash Payment 
performPayment Method called
Perform Card Payment 

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

>>>Return to Spring Tutorial Page


Related Topics

  1. ApplicationContextAware And BeanNameAware Interfaces in Spring Framework
  2. Spring Bean Life Cycle
  3. @Required Annotation in Spring Framework
  4. registerShutdownHook() Method in Spring Framework
  5. Autowiring in Spring Using @Autowired and @Inject Annotations

You may also like-

  1. How to Inject Prototype Scoped Bean into a Singleton Bean in Spring
  2. How to Read Properties File in Spring Framework
  3. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  4. Java Reflection API Tutorial
  5. Java Stream API Examples
  6. How LinkedList Class Works Internally in Java
  7. Java Lambda Expressions Interview Questions And Answers
  8. Constructor Chaining in Java

No comments:

Post a Comment