需求:通過配置文件,能夠使得新的一個service層類替代jar包中原有的類文件。
項目原因,引用了一些成型產品的jar包,已經不能對其進行修改了。
故,考慮採用用新的類替換jar包中的類。
實現思路:在配置文件中配置新老類的全類名,讀取配置文件後,通過spring初始化bean的過程中,移除spring容器中老類的bean對象,手動註冊新對象進去,bean名稱和老對象一致即可。
jar包中的老對象是通過@Service註冊到容器中的。
新的類因爲是手動配置,不需要添加任何註解。
實現的方法如下:
@Component
public class MyBeanPostProcessor implements ApplicationContextAware, BeanPostProcessor {
@Autowired
private AutowireCapableBeanFactory beanFactory;
@Autowired
private DefaultListableBeanFactory defaultListableBeanFactory;
static HashMap ReplaceClass;
static String value = null;
static {
try {
value = PropertiesLoaderUtils.loadAllProperties("你的配置文件路徑").getProperty("replaceClass");
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("properties value........"+value);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("對象" + beanName + "開始實例化");
System.out.println("類名" + bean.getClass().getName() + "是啥");
if(StringUtils.contains(value,bean.getClass().getName())){
System.out.println("找到了需要進行替換的類。。。。。。。。。。。");
boolean containsBean = defaultListableBeanFactory.containsBean(beanName);
if (containsBean) {
//移除bean的定義和實例
defaultListableBeanFactory.removeBeanDefinition(beanName);
}
String temp = value;
String tar_class = temp.split(bean.getClass().getName())[1].split("#")[1].split(",")[0];
System.out.println(tar_class);
try {
Class tar = Class.forName(tar_class);
Object obj = tar.newInstance();
//註冊新的bean定義和實例
defaultListableBeanFactory.registerBeanDefinition(beanName, BeanDefinitionBuilder.genericBeanDefinition(tar.getClass()).getBeanDefinition());
//這裏要手動注入新類裏面的依賴關係
beanFactory.autowireBean(obj);
return obj;
} catch (Exception e) {
e.printStackTrace();
}
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
}
配置文件中的格式採用下面的樣式 :
replaceClass=gov.df.fap.service.OldTaskBO#gov.df.newmodel.service.NewTaskBO
在啓動的時候,會找到容器中的老的bean,將其remove掉,然後手動註冊新的bean到容器中。