前言
在企业产品化项目中,各个业务处理一般都有标准(通用)实现逻辑,以应对该产品(业务)面对的常见通用型需求。而如果产品下发给某个客户,且该客户要求某个业务逻辑需要做部分微小的个性化处理时,通常有以下几种处理方式:
其一,客户化的业务实现交给非产品模块,即交给个性化模块处理特殊业务,接口调用时同步改成调用该个性化接口,对产品层无影响,但另一方面对于较为复杂、关联处理较多的业务逻辑,显然改动点就大了;
其二,在产品代码中通过增加配置的方式,来处理该客户的个性逻辑,配置不启用也不会影响现有产品主逻辑,但是长此以往把各个客户的特殊处理都杂糅进来后,产品的代码将会变得十分臃肿和难以维护;
其三,如果产品代码在设计时预留了扩展的接口,则也只需要在个性化模块中做扩展实现即可,也不影响产品代码,但通常客户的需求是难以猜测的,具体怎么留有扩展也十分考验产品开发团队的业务和技术水平;
本文针对此问题,结合实际场景,分享一种通过继承原有实现类的
bean
方式,达到重写其原有方法,又不影响原先bean
之间的依赖和调用关系。
定义注解OverrideBean
自定义重写bean注解,用于标注该
bean
是重写原来实现的类的bean
(替代产品化实现bean
)
package mine.code.config.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义重写bean注解
*
* @author BlueDriver
* @email cpwu@foxmail.com
* @date 2022/6/27 20:01
* -----------------------------------------
* Gitee: https://gitee.com/BlueDriver
* Github: https://github.com/BlueDriver
* -----------------------------------------
*/
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OverrideBean {
}
定义OverrideBeanDefinitionRegistryPostProcessor
用于将重写的bean替换其原先的bean(个性化实现bean替换产品实现bean),具体实现原理可结合注释和下文示例理解,建议配合源码食用(源码链接见文章末尾)
package mine.code.config.processor;
import mine.code.config.annotation.OverrideBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.