BeanPostProcessor是创建每个类时都会去执行的一个接口,postProcessBeforeInitialization是在类初始化之前调用的一个方法,创建的对象的引用会指向改方法的返回值对象。调用过程示例如下:
ClassA classA = new ClassA();
classA = postProcessBeforeInitialization(classA, "classA");
所以我们可以通过该方法就可以实现动态替换我们的bean。
package com.example.hellododo.data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* @author Liangzhifeng
* date: 2018/9/4
*/
@Slf4j
@Component
public class LocalProcessor implements BeanPostProcessor {
@Autowired
private DefaultListableBeanFactory defaultListableBeanFactory;
private String targetBeanName = "test22";
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (StringUtils.endsWithIgnoreCase(beanName, targetBeanName)) {
boolean containsBean = defaultListableBeanFactory.containsBean(targetBeanName);
if (containsBean) {
//移除bean的定义和实例
defaultListableBeanFactory.removeBeanDefinition(targetBeanName);
}
//注册新的bean定义和实例
defaultListableBeanFactory.registerBeanDefinition(targetBeanName, BeanDefinitionBuilder.genericBeanDefinition(Test55.class).getBeanDefinition());
bean = null;
return new Test55();
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
在事件监听器中,分别注入和获取Bean对象。分别打印两个对象的类名,可以看到两个类名都是com.example.hellododo.data.Test55
package com.example.hellododo.data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
/**
* @author Liangzhifeng
* date: 2018/9/12
*/
@Slf4j
@Component
public class LocalEventListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private DefaultListableBeanFactory defaultListableBeanFactory;
private boolean doFist = true;
@Autowired
private Test22 test22;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
Test22 bean = defaultListableBeanFactory.getBean(Test22.class);
if (doFist) {
if (bean != null) {
log.info("autowiredClassName={}, beanClassName={}", test22.getClass().getName(), bean.getClass().getName());
doFist = false;
}
}
}
}
package com.example.hellododo.data;
import lombok.Data;
/**
* @author Liangzhifeng
* date: 2018/9/6
*/
@Data
public class Test {
private String data;
}
@Component
package com.example.hellododo.data;
import org.springframework.stereotype.Component;
/**
* @author Liangzhifeng
* date: 2018/9/6
*/
@Component
public class Test22 extends Test{
}
package com.example.hellododo.data;
/**
* @author Liangzhifeng
* date: 2018/9/6
*/
public class Test55 extends Test22{
}