BeanPostProcessor是創(chuàng)建每個(gè)類(lèi)時(shí)都會(huì)去執(zhí)行的一個(gè)接口,postProcessBeforeInitialization是在類(lèi)初始化之前調(diào)用的一個(gè)方法旭等,創(chuàng)建的對(duì)象的引用會(huì)指向改方法的返回值對(duì)象按厘。調(diào)用過(guò)程示例如下:
ClassA classA = new ClassA();
classA = postProcessBeforeInitialization(classA, "classA");
所以我們可以通過(guò)該方法就可以實(shí)現(xiàn)動(dòng)態(tài)替換我們的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的定義和實(shí)例
defaultListableBeanFactory.removeBeanDefinition(targetBeanName);
}
//注冊(cè)新的bean定義和實(shí)例
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;
}
}
在事件監(jiān)聽(tīng)器中走贪,分別注入和獲取Bean對(duì)象大渤。分別打印兩個(gè)對(duì)象的類(lèi)名,可以看到兩個(gè)類(lèi)名都是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{
}