SoFunction
Updated on 2025-04-05

How to rewrite built-in beans (Controller, Service, etc.)

Spring rewrites built-in beans (Controller, Service, etc.)

Scene

  • One of themTestControllerClass, the current source code project demo depends on this
  • The demo project is started normally, and the TestController is initialized.TestControllerThe interface provided in/svc1/test1/svc1/test2/svc1/test3All are accessible normally.
  • Because of the interface/svc1/test2The logical processing in the corresponding method does not meet the requirements, so this method needs to be rewrited.
  • The interface isPackage, the source code cannot be modified directly.

Processing method 1 (simple processing)

The main idea is to register the PostProcessor after Spring registers a bean.The TestController in , is removed from the context.

This enables our newly created rewrite class inheriting TestController to be loaded and instantiated normally without repeated error collisions with PathMapping.

The main code is as follows:

/**
  * Exclude beans in containers
  *
  * @author Shan Hongyu
  * @since 2024/11/28 13:14
  */
@Slf4j
@Configuration
public class ExcludeComponentConfiguration implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        (getDefaultBeanName());
        (getDefaultBeanName());
    }

    /**
      * Get the default beanName of spring according to class class
      *
      * @param clazz clazz
      * @return String
      */
    private String getDefaultBeanName(Class<?> clazz) {
        // Test the default BeanName of the inner class        // ((()))
        // Used before spring 6.0 ()        return ((()));
    }
}
/**
  * Rewrite the FileController class
  *
  * @author Shan Hongyu
  * @since 2024/11/28 12:03
  */
@RestController //The annotation must be included, and those annotations of Mapping are not requiredpublic class OverrideFileController extends FileController {

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

}

Processing method 2 (custom annotation)

We can customize annotation@ExcludeBean, and then use this annotation to easily exclude classes that need to be excluded anywhere.

1. Custom annotations

/**
  * Custom annotations to exclude beans that would have been in the spring context.
  * It is generally used to delete a bean that cannot be modified, and then customize a class to inherit the original class and then rewrite a specific method to replace the original class.
  *
  * @author Shan Hongyu
  * @since 2024/12/5 9:36
  */
@Target({})
@Retention()
@Documented
@Component
public @interface ExcludeBean {
    Class<?>[] clazz() default {};
    String[] name() default {};
}

2. Automatic configuration class

/**
  * Exclude Spring Bean automatic configuration classes
  * @author Shan Hongyu
  * @since 2024/12/5 9:13
  */
@AutoConfiguration
public class ExcludeBeanAutoConfiguration implements BeanDefinitionRegistryPostProcessor {
    
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // not implemented
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        if (beanFactory instanceof BeanDefinitionRegistry bdr) {
            (())
                    .map(item -> (item, , false)).filter(Objects::nonNull)
                    .flatMap(item -> ((()),
                            (()).map(cls -> 
                                    ((())))))
                    .distinct()
                    .forEach(bdr::removeBeanDefinition);
        }
    }

}

3. Configure automatic configuration

@AutoConfigurationFor details on how to enable automatic configuration annotations, please refer to the article:SpringBoot Automatic Configuration @AutoConfiguration added in version 2.7

4. Annotation usage examples

Let's rewrite a Controller method. The main application scenario is: the target Controller is depended on through the jar package, and we need to rewrite one of the method logic.

/**
  * Rewrite specific methods in the Controller class TestApi
  *
  * @author Shan Hongyu
  * @since 2024/11/28 9:06
  */
@ExcludeBean(clazz = )
@RestController
public class OverrideTestApi extends TestApi {

    /**
      * Rewrite Hello method
      *
      * @return String
      */
    @Override
    public String hello() {
        return "Hello, Override!";
    }

}

Replenish

If it is based on one interface and then there are multiple implementation classes, the use is based on interface injection.

Can also be used@PrimaryAnnotations to modify specific classes.

But forControllerAs well as other methods that are not defined and injected through interfaces, we need to use the methods in this article.

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.