美文网首页
基于spring的一种代码拆分的方法

基于spring的一种代码拆分的方法

作者: 小王ovo | 来源:发表于2023-02-28 11:26 被阅读0次

在写业务代码的时候我有时想写一些策略模式工厂模式类似的代码拆分业务,可是在spring下有一些局限性.我们已经使用了spring来管理对象的初始化,我们就没法写一些类似于

map.put("key",new object())

的代码.其次同一接口下多个实现类需要使用

@Qualifier("a")
@Qualifier("b")

来区分,那么最终我们的代码大概会写成这个样子

public class WxEventHandleFactory {

    @Autowired
    @Qualifier("scan")
    private WxEventHandle scanHandle;

    @Autowired
    @Qualifier("subscribe")
    private WxEventHandle subscribeHandle;

    @Autowired
    @Qualifier("unsubscribe")
    private WxEventHandle unsubscribeHandle;

    public WxEventHandle getHandle(String event) {
        if (WxEventType.SUBSCRIBE.getCode().equals(event)) {
            return subscribeHandle;
        } else if (WxEventType.UNSUBSCRIBE.getCode().equals(event)) {
            return unsubscribeHandle;
        } else if (WxEventType.SCAN.getCode().equals(event)) {
            return scanHandle;
        }
        return null;
    }
}

这段代码就是根据微信公众号不同的消息,拆分了不同处理代码.不好的点就是我们的策略方法会不断的膨胀的,但这也不是不能接受,我在flink的某个连接redis做状态存储的开源项目下也看到过更大的类似方法,不过是用switch 拆分罢了.

那么我们有没有更好的办法呢?

我们可不可以通过一些类似标记的方式给我们业务类打上独有的标记?

注解是一个不错的方案

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CallBack {

    TypeEnum[] value();
}

这里value为什么是一个数组呢,因为我希望多个策略使用同一个类处理.

我们怎么从spring的管理中获取这些被我们标记的类呢?

bean实例化后会注入ApplicationContext

@Component
public class MyBean {
    @Autowired
    private ApplicationContext context;
}

接下来我们只需要将标有@CallBack的类统一使用数据结构保存起来,每次根据不同TypeEnum获取即可,其次为了方便调用,我们所有的业务类肯定需要实现相同的方法

public interface BaseStrategyCallBack {
    void doMethod(MyContext myContext);
}

@PostConstruct(bean初始化前执行,相当于init)

@Component
public class FactoryStrategy {

    private static Map<TypeEnum, BaseStrategyCallBack> map = new ConcurrentHashMap<>();

    @Autowired
    private ApplicationContext context;

    public static BaseStrategyCallBack createDoMethod(TypeEnum typeEnum) {
        return map.get(doTypeEnum);
    }


    @PostConstruct
    public void init() {
        Map<String, Object> beansMap = context.getBeansWithAnnotation(CallBack.class);
        beansMap.values()
                .forEach(i -> {
                    OrderCallBack doTypeAnnotation = i.getClass().getAnnotation(CallBack.class);
                    for(ItemTypeEnum e : doTypeAnnotation.value()){
                        map.put(e, (BaseStrategyCallBack) i);
                    }
                });
    }
}

编写业务类

@Log4j2
@Service
@CallBack(TypeEnum.test)
public class StrategyTest implements BaseStrategyCallBack {

    @Override
    public void doMethod(MyContext myContext) {
        //业务逻辑
    }
}

调用

FactoryStrategy.createDoMethod(typeEnum).doMethod(myContext);

至此我们就实现了基于spring的代码拆分,根据不同的枚举获取不同的业务类.

ps:我平时是不看spring相关书籍去学习的,当工作中需要的时候可能会点进去看一丢丢源码也是属于看过就忘.但是有一点就是一定要去看官方文档,毕竟spring的文档算是开源项目里最完善的一批了.理解了ioc,aop.你就有了思考的脉络,剩下东西,我愿意称为机制而不是技术,所以机制的东西,在不会的时候去看文档查一查就好.况且现在还有chatgpt,查文档更是一绝.其次我也很少看设计模式相关的东西,因为只要你心中有类,接口,抽象类的概念,那你就可以梳理代码的结构,以不变应万变我觉得才是更好的方式.当然这是我个人极端的想法,设计模式还是需要看的,只是我目前还没有多余的时间,之前一直都是写一些底层原理的文章,是因为我个人比较痴迷这些东西.最近尝试写一些比较业务的东西,展示一下工作中的一些思路.

相关文章

  • 代码重构

    一、大函数拆分 不让一个方法,承载过多的功能,代码偏多时,考虑进行拆分。拆分的代码方便复用! 参考:https:/...

  • SpringBoot

    Spring 组件代码轻量级,配置重量级。 开始基于xml配置。 spring 2.5基于主键扫描 spring ...

  • 3.服务如何拆分

    服务拆分的几种方法 纵向拆分(基于业务逻辑拆分)是从业务维度进行拆分。标准是按照业务的关联程度来决定,关联比较密切...

  • Spring Web Flow

    Spring Web Flow :流程,基于Spring MVC 的DispatchServlet 使用方法 配置...

  • golang xorm mysql代码生成器(java,go)

    基于go,go template的数据层代码生成器,支持生成基于xorm go,spring jpa的数据层代码生...

  • mysql读写分离(1)---springboot+aop+tk

    前言 实现mysql读写分离有两种,一种是基于代码实现(spring提供的抽象类AbstractRoutingDa...

  • Spring Cloud - Eureka服务注册与发现

    说明:文中的示例代码基于Spring Cloud Finchley版本 1.服务注册中心 Spring Cloud...

  • SpringBoot集成MyBatis-Plus代码生成器

    1.说明 本文详细介绍Spring Boot集成MyBatis-Plus代码生成器的方法。基于一个创建好的Spri...

  • [react native] 拆分bundle 与 androi

    1 拆分 bundle 代码(基于 react native 最新版本 0.55.4)https://github...

  • Spring Security

    Spring Security 学习 Spring Security是一种基于Spring AOP和Servlet...

网友评论

      本文标题:基于spring的一种代码拆分的方法

      本文链接:https://www.haomeiwen.com/subject/vthlldtx.html