1. BeanFactoryPostProcessor:
I give this example as I see this answer: https://stackoverflow.com/a/2349891/4251461
He initially chose BeanFactory for use in integration/performance tests since He didn't want to load the entire application for testing isolated beans. However, He think BeanFactory doesn't support classpath XML configuration. So BeanFactory and ApplicationContext each provide a crucial feature I wanted, but neither did both.
He implements his own ApplicationContext which extends ClassPathXmlApplicationContext.
Here he could use BFPP instead of custom ApplicationContext.
public class LazyInitBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
bd.setLazyInit(true);
}
}
}
configure it in spring container like other regular beans:
<bean class="com.example.LazyInitBeanFactoryPostProcessor" />
You can also see the source of PropertyPlaceholderConfigurer and PropertyOverrideConfigurer in spring.
2. InitializingBean:
As Sotirios Delimanolis said: The InitializingBean interface is often used along with the FactoryBean interface. It helps to initialize the factory before it produces an object.
Here is an example.
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import java.security.MessageDigest;
public class SampleDigesterFactory implements FactoryBean<MessageDigest>, InitializingBean {
MessageDigest messageDigest;
String algorithmName = "MD5";
public MessageDigest getObject() throws Exception {
return messageDigest;
}
public Class<?> getObjectType() {
return MessageDigest.class;
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() throws Exception {
messageDigest = MessageDigest.getInstance(algorithmName);
}
public String getAlgorithmName() {
return algorithmName;
}
public void setAlgorithmName(String algorithmName) {
this.algorithmName = algorithmName;
}
}
import java.security.MessageDigest;
public class SampleDigester {
private MessageDigest messageDigest;
public void digestMessage(String message) {
System.out.println("digest message:" + message);
System.out.println("result: " + messageDigest.digest(message.getBytes()));
}
public MessageDigest getMessageDigest() {
return messageDigest;
}
public void setMessageDigest(MessageDigest messageDigest) {
this.messageDigest = messageDigest;
}
}
configure beans in spring container:
<bean id="messageDigesterFactoryMD5" class="com.example.SampleDigesterFactory" />
<bean id="messageDigesterFactorySHA1" class="com.example.SampleDigesterFactory" p:algorithmName="SHA1" />
<bean id="sampleDigesterMD5" class="com.example.SampleDigester" p:messageDigest-ref="messageDigesterFactoryMD5" />
<bean id="sampleDigesterSHA1" class="com.example.SampleDigester" p:messageDigest-ref="messageDigesterFactorySHA1" />
Test it:
SampleDigester sampleDigesterMD5 = context.getBean("sampleDigesterMD5", SampleDigester.class);
SampleDigester sampleDigesterSHA1 = context.getBean("sampleDigesterSHA1", SampleDigester.class);
sampleDigesterMD5.digestMessage("Hello World!");
sampleDigesterSHA1.digestMessage("Hello World!");
The output is:
digest message:Hello World!
result: [B@19d02cb
digest message:Hello World!
result: [B@1753b6d
The spring reference says:
The FactoryBeanconcept and interface is used in a number of places within the Spring Framework;more than 50 implementations of the FactoryBeaninterface ship with Spring itself.
3. BeanPostProcessor:
You can refer to source of RequiredAnnotationBeanPostProcessor in spring.
a BeanPostProcessorimplementation that ships with the Spring distribution which ensures that JavaBean properties on beans that are marked with an (arbitrary) annotation are actually (configured to be) dependency-injected with a value.