Spring Core | BeanFactoryPostProcessor | Example

In Spring, the BeanFactoryPostProcessor is a functional interface that contains a abstract method postProcessBeanFactory. It allows us to modify the Spring context’s bean definitions before any beans get created. 

BeanFactoryPostProcessor can create new bean definitions or modify existing ones.

Since BeanFactoryPostProcessor should be called before other bean types are formed, it must be registered as a static method level.

BeanFactoryPostProcessor example

We are creating a simple maven project. You could clone the code from our GitHub repo.

Final Project Directory


Complete pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>com.knf.dev.demo</groupId>
<
artifactId>spring-beanfactorypostprocessor-example</artifactId>
<
version>0.0.1-SNAPSHOT</version>
<
name>spring-beanfactorypostprocessor-example</name>

<
properties>
<
maven.compiler.source>17</maven.compiler.source>
<
maven.compiler.target>17</maven.compiler.target>
<
project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</
properties>
<
dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.0</version>
</dependency>

</
dependencies>
</
project>


Create ABean

package com.knf.dev.demo;

public class ABean {
String aProperty;

public void setAProperty(String aProperty) {
this.aProperty = aProperty;
}

public void doStuff() {
System.out.println("aProperty: " + aProperty);
}
}


Create CustomABeanFactoryPostProcessor

Here we have CustomABeanFactoryPostProcessorand it implements BeanFactoryPostProcessor. Here we are registering a new bean of ABean type. The new bean is registered with registerBeanDefinition method.
package com.knf.dev.demo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;

public class CustomABeanFactoryPostProcessor
implements BeanFactoryPostProcessor {


@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
System.out.println("Inside 'A'postProcessBeanFactory");
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClass(ABean.class);
bd.getPropertyValues().add("aProperty", "A property");

((DefaultListableBeanFactory) beanFactory)
.registerBeanDefinition("myABean", bd);
}
}


Create Config

To register this class we are using the Config class with a static method. And this static method annotated with @Bean. That informs Spring to create a bean before any other bean.
package com.knf.dev.demo;

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

@Configuration
public class Config {

@Bean
public static CustomABeanFactoryPostProcessor myBean() {
return new CustomABeanFactoryPostProcessor();
}
}


Create BBean

package com.knf.dev.demo;

public class BBean {
String bProperty;

public void setBProperty(String bProperty) {
this.bProperty = bProperty;
}

public void doStuff() {
System.out.println("bProperty: " + bProperty);
}
}


Create CustomBBeanFactoryPostProcessor

Since BeanFactoryPostProcessor is a functional interface it can be used as the assignment target for a lambda expression or method reference.
package com.knf.dev.demo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomBBeanFactoryPostProcessor {

@Bean
public static BeanFactoryPostProcessor beanFactoryPostProcessor() {
return beanFactory -> {
System.out.println("Inside 'B'postProcessBeanFactory");
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClass(BBean.class);
bd.getPropertyValues().add("bProperty", "B property");

((DefaultListableBeanFactory) beanFactory)
.registerBeanDefinition("myBBean", bd);
};
}
}


Create Driver class for testing - TestBeanFactoryPostProcessor

The AnnotationConfigApplicationContext is a type of ApplicationContext which can take class annotated with @Configuration. The ApplicationContext is responsible for instantiating, configuring, and assembling the beans.

The ApplicationContext interface provides the getBean() method to retrieve the bean from the spring container.

We can retrieve bean by 
  • Type 
  • Name 
  • Name and Type.
package com.knf.dev.demo;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestBeanFactoryPostProcessor {
public static void main(String[] args) {

AnnotationConfigApplicationContext contextA =
new AnnotationConfigApplicationContext(Config.class);
ABean aBean = contextA.getBean(ABean.class);
//ABean aBean = (ABean) contextA.getBean("myABean");
//ABean aBean = contextA.getBean("myABean",ABean.class);
aBean.doStuff();

AnnotationConfigApplicationContext context2 =
new AnnotationConfigApplicationContext(
CustomBBeanFactoryPostProcessor.class);
BBean bBean = context2.getBean(BBean.class);
//BBean bBean = (BBean) context2.getBean("myBBean");
//BBean bBean = context2.getBean("myBBean",BBean.class);
bBean.doStuff();
}
}


Console Output: 

Inside 'A'postProcessBeanFactory

aProperty: A property

Inside 'B'postProcessBeanFactory

bProperty: B property


Source code  

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Spring Boot + Mockito simple application with 100% code coverage

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete