Spring 重写内置 Bean(Controller、Service 等)

阅读 17

2024-12-02


场景

  • svc1.jar 中有一个 TestController 类,当前源代码工程 demo 依赖了这个 svc1.jar
  • 当前 demo 工程启动正常,TestController 被初始化,TestController 中提供的接口 /svc1/test1/svc1/test2/svc1/test3 均可以正常访问。
  • 因接口 /svc1/test2 对应的方法中逻辑处理不满足需求,需要对这个方法进行重写处理。
  • 该接口在 svc1.jar 包,不能直接修改源代码。

处理方式

主要思路是在 Spring 注册 Bean 之后进行 PostProcessor 时,将已经注册的 svc1.jar 中的 TestController 从上下文中删除。使我们新创建的继承 TestController 的重写类能被正常加载实例化,而不出现 PathMapping 重复的报错冲突。

主要代码如下:

/**
 * 排除容器中的Bean
 * 
 * @author 单红宇
 * @since 2024/11/28 13:14
 */
@Slf4j
@Configuration
public class ExcludeComponentConfiguration implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        registry.removeBeanDefinition(getDefaultBeanName(FileController.class));
        registry.removeBeanDefinition(getDefaultBeanName(UserController.class));
    }

    /**
     * 根据类 class 获取 spring 默认的 beanName
     *
     * @param clazz clazz
     * @return String
     */
    private String getDefaultBeanName(Class<?> clazz) {
        // 测试内部类 AutowireUtils.ObjectFactoryDelegatingInvocationHandler 的默认 BeanName
        // StringUtils.uncapitalizeAsProperty(ClassUtils.getShortName(AutowireUtils.ObjectFactoryDelegatingInvocationHandler.class.getName()))
        return StringUtils.uncapitalizeAsProperty(ClassUtils.getShortName(clazz.getName()));
    }
}

/**
 * 重写FileController类
 * 
 * @author 单红宇
 * @since 2024/11/28 12:03
 */
@RestController //该注解必须要有,Mapping那些注解不需要
public class OverrideFileController extends FileController {

    @Override
    public void fileDownload(@RequestParam("fileId") Long fileId,
                             @RequestParam("isInline") Integer isInline,
                             HttpServletResponse response, HttpServletRequest request) {
        System.out.println("override filedownload...");
    }

}

(END)


精彩评论(0)

0 0 举报