Spring override container bean annotation implementation @OverrideBean
During project development, sometimes a third-party framework will automatically inject beans into Spring containers. When we have the need to modify the corresponding built-in bean implementation, we can use the method of replacing the built-in beans by replacing the columns. You need to pay attention to the following two points:
- 1. When the corresponding bean is used in other places, it is based on interface injection.
- 2. If it is not a bean based on interface injection, you may need to rewrite the same package name in this way (there may be problems and is not recommended).
From the above two points, we can also draw a conclusion, that is, the benefits of "interface-based programming".
Please refer to the code for specific implementation
(Code snippet, for reference only, modified according to the actual usage scenario):
import ; import ; import ; import ; /** * Overwrite Beans in Spring containers * * @author shanhy * @date 2021/4/25 13:40 */ @Retention() @Target() public @interface OverrideBean { /** * Name of the bean that needs to be replaced * * @return */ String value(); }
import org.; import org.; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; /** * Rewrite the configuration class of the bean * * @author shanhy * @date 2021/4/25 13:41 */ @Configuration public class OverrideBeanConfiguration implements BeanDefinitionRegistryPostProcessor, BeanFactoryAware { private static final Logger log = (); private BeanFactory beanFactory; @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { ("searching for classes annotated with @OverrideBean"); // Customize Scanner to scan the specified annotation under classpath ClassPathOverrideBeanAnnotationScanner scanner = new ClassPathOverrideBeanAnnotationScanner(registry); try { // Get the package path List<String> packages = (); if (()) { for (String p : packages) { ("Using auto-configuration base package: {}", p); } } // Scan all loaded packages ((packages)); } catch (IllegalStateException ex) { ("could not determine auto-configuration package, automatic OverrideBean scanning disabled.", ex); } } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException { } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { = beanFactory; } private static class ClassPathOverrideBeanAnnotationScanner extends ClassPathBeanDefinitionScanner { ClassPathOverrideBeanAnnotationScanner(BeanDefinitionRegistry registry) { super(registry, false); // Set filter. Scan only @OverrideBean addIncludeFilter(new AnnotationTypeFilter()); } @Override public Set<BeanDefinitionHolder> doScan(String... basePackages) { List<String> overrideClassNames = new ArrayList<>(); // Scan all packages to specify the beans specified by annotationClass Set<BeanDefinitionHolder> beanDefinitions = (basePackages); GenericBeanDefinition definition; for (BeanDefinitionHolder holder : beanDefinitions) { definition = (GenericBeanDefinition) (); // Get the class name and create a Class object String className = (); Class<?> clazz = classNameToClass(className); // parse the value on the annotation OverrideBean annotation = (clazz).getAnnotation(); if (annotation == null || ().length() == 0) { continue; } // Replace the bean with the specified name in the value using the currently loaded @OverrideBean specified if ((getRegistry()).containsBeanDefinition(())) { getRegistry().removeBeanDefinition(()); getRegistry().registerBeanDefinition((), definition); (()); } } ("found override beans: " + overrideClassNames); return beanDefinitions; } //Reflection gets the Class object through the class name private Class<?> classNameToClass(String className) { try { return (className); } catch (ClassNotFoundException e) { ("create instance failed.", e); } return null; } } }
Summarize
The above is personal experience. I hope you can give you a reference and I hope you can support me more.