Skip to content

覆盖SpringBean 的方法

有时候,是原来的 bean 有问题,有时候,是提供默认 bean 作为默认实现并让用户扩展。需求实际

同包同类名

  • 方式简单粗暴,可以直接覆盖掉jar包中的类,spring项目会优先加载自定义的类。

@Primary

  • 该方法适用于接口实现类,自己创建一个原jar包接口的实现类,然后类上加上@Primary注解,spring则默认加载该类实例化出的Bean

@Bean

  • 若原来的 bean 使用了 @ConditionalOnMissingBean,如果你自己创建了一个一样的Bean,则原Bean就不创建了,达到覆盖效果

BeanPostProcessor

  • BeanPostProcessor
  • BeanFactoryPostProcessor
  • BeanDefinitionRegistryPostProcessor
java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.Map;
 
/**
 * @author amdin
 */
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
 
    private Logger logger = LoggerFactory.getLogger(this.getClass());
 
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        logger.info("bean 定义查看和修改...");
 
        String beanName = "myTestService";
 
        // 先移除原来的bean定义
        beanDefinitionRegistry.removeBeanDefinition(beanName);
 
        // 注册我们自己的bean定义
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(MyTestServiceIpml.class);
        // 如果有构造函数参数, 有几个构造函数的参数就设置几个  没有就不用设置
        beanDefinitionBuilder.addConstructorArgValue("构造参数1");
        beanDefinitionBuilder.addConstructorArgValue("构造参数2");
        beanDefinitionBuilder.addConstructorArgValue("构造参数3");
        // 设置 init方法 没有就不用设置
        beanDefinitionBuilder.setInitMethodName("init");
        // 设置 destory方法 没有就不用设置
        beanDefinitionBuilder.setDestroyMethodName("destory");
        // 将Bean 的定义注册到Spring环境
        beanDefinitionRegistry.registerBeanDefinition("myTestService", beanDefinitionBuilder.getBeanDefinition());
    }
 
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        // bean的名字为key, bean的实例为value
        Map<String, Object> beanMap = configurableListableBeanFactory.getBeansWithAnnotation(RestController.class);
        logger.info("所有 RestController 的bean {}", beanMap);
    }
}

Released under the MIT License.