场景
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 重复的报错冲突。
主要代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
@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)); }
private String getDefaultBeanName(Class<?> clazz) { return org.springframework.util.StringUtils.uncapitalizeAsProperty(ClassUtils.getShortName(clazz.getName())); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
|
@RestController public class OverrideFileController extends TestController {
@Override public void fileDownload(@RequestParam("fileId") Long fileId, @RequestParam("isInline") Integer isInline, HttpServletResponse response, HttpServletRequest request) { System.out.println("override filedownload..."); } }
|
处理方式二(自定义注解)
我们可以自定义一个注解 @ExcludeBean,然后使用该注解来很方便的在任何地方来排除需要排除的类。
1、自定义注解
1 2 3 4 5 6 7 8 9 10 11 12
|
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface ExcludeBean { Class<?>[] clazz() default {}; String[] name() default {}; }
|
2、自动配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
@AutoConfiguration public class ExcludeBeanAutoConfiguration implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { }
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { if (beanFactory instanceof BeanDefinitionRegistry bdr) { Arrays.stream(beanFactory.getBeanNamesForAnnotation(ExcludeBean.class)) .map(item -> beanFactory.findAnnotationOnBean(item, ExcludeBean.class, false)).filter(Objects::nonNull) .flatMap(item -> Stream.concat(Arrays.stream(item.name()), Arrays.stream(item.clazz()).map(cls -> org.springframework.util.StringUtils.uncapitalizeAsProperty(ClassUtils.getShortName(cls.getName()))))) .distinct() .forEach(bdr::removeBeanDefinition); } }
}
|
3、配置自动配置
@AutoConfiguration 自动配置注解启用。
4、注解使用示例
我们来重写一个 Controller 的方法,主要应用场景是:目标 Controller 是通过 jar 包依赖过来的,并且我们需要重写其中的一个方法逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
@ExcludeBean(clazz = TestApi.class) @RestController public class OverrideTestApi extends TestApi {
@Override public String hello() { return "Hello, Override!"; } }
|
原文链接:https://shanhy.blog.csdn.net/article/details/144110051