概述
工作中會經常會需要重寫jar包中的一個類,開源的jar包或者是其他項目提供的share包,比較通用的做法是下載源碼下來,修改後重新打包。但是很多時候我們只是重寫一個類,下載源碼打包太過繁瑣,而且有可能別人的share沒有提供源碼下載。
可以通過下面幾種方式重寫:
1、直接同包路徑,同報名,進行替換
這種方式簡單粗暴,前提必須是同包路徑,同類名。可以直接覆蓋掉jar包中的類,spring項目會優先加載自定義的類。
比如重寫:DefaultResourceFactory類
2)繼承要替換的類,在配置類中進行配置,返回其子類
1)首先創建一個新的bean,繼承需要被重寫的bean
public class MyHealthMessageQueueLogService extends HealthMessageQueueLogService{
//需要被重寫的方法
}
2)在啓動類中排除父類
@ComponentScan(excludeFilters = {@Filter(type = FilterType.ASSIGNABLE_TYPE, value = HealthMessageQueueLogService.class)})
3)在配置類中創建子類
@Configuration
public class MessageQueueLogConfig {
@Bean
public HealthMessageQueueLogService healthMessageQueueLogService(){
return new MyHealthMessageQueueLogService();
}
}
3)使用BeanDefinitionRegistryPostProcessor
/**
* Created by zhangshukang on 2019/9/16.
*/
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
private static String SPECIAL_OVERRIDE_BEAN = "healthMessageQueueLogService";
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
boolean isContainsSpecialBean = ((DefaultListableBeanFactory) registry).containsBean(SPECIAL_OVERRIDE_BEAN);
if (isContainsSpecialBean) {
AnnotatedBeanDefinition healthMessageBeanDefinition = (AnnotatedBeanDefinition) registry.getBeanDefinition(SPECIAL_OVERRIDE_BEAN);
if (healthMessageBeanDefinition != null) {
AnnotatedGenericBeanDefinition myBeanDefinition = new AnnotatedGenericBeanDefinition(healthMessageBeanDefinition.getMetadata());
//忽略beanClass originatingBeanDefinition字段
BeanUtils.copyProperties(healthMessageBeanDefinition, myBeanDefinition,"beanClass","originatingBeanDefinition");
//設置自定義的bean class
myBeanDefinition.setBeanClass(MyHealthMessageQueueLogService.class);
//重新加載自定義的bean class
try {
myBeanDefinition.resolveBeanClass(Thread.currentThread().getContextClassLoader());
registry.registerBeanDefinition(SPECIAL_OVERRIDE_BEAN,myBeanDefinition);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}