设计模式 | 工厂模式 spring boot demo

先看一个工厂类

package com.example.demo.factory;

import com.example.demo.factory.annoation.Processor;
import com.example.demo.factory.service.ProcessHandle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * 工厂类,spring容器初始化后注入实例到内存中
 *
 * @author mdl
 * @date 2020/4/2 11:08
 */
@Service
public class ProcessorFactory {

    private final Map<String, ProcessHandle> processHandleHashMap = new HashMap<>();

    @Autowired
    private ApplicationContext applicationContext;

    @PostConstruct
    public void init() {
        // 根据注解类型获取所有实现的实例
        Map<String, ProcessHandle> processHandleBeans = applicationContext.getBeansOfType(ProcessHandle.class);
        for (ProcessHandle processHandle : processHandleBeans.values()) {
            if (processHandle.getClass().isAnnotationPresent(Processor.class)) {
                Processor processorAnnotation = processHandle.getClass().getAnnotation(Processor.class);
                processHandleHashMap.put(processorAnnotation.value().getValue(), processHandle);

            }
        }
    }

    public ProcessHandle getProcessHandleByKey(String operate) {
        return processHandleHashMap.get(operate);
    }
}

 

几个知识点

  1.  @PostConstruct这个注解在spring中的切入点:Constructor >> @Autowired >> @PostConstruct

    这个可在工厂类里初始化,利用 applicationContext.getBeansOfType(SomeInterface.class);获取到当前注入的 SomeInterface的实现类

  2.  我们可以在实现类上加上自定义注解,通过自定义注解将实现类的实例分类到内存中

一、接口类

package com.example.demo.factory.service;

/**
 * @author mdl
 * @date 2020/4/3 13:34
 */
public interface ProcessHandle {

    /**
     * 处理器接口
     *
     * @param obj
     * @return
     */
    public Object dealProcess(Object obj);

}

二、枚举

package com.example.demo.factory.enums;

/**
 * 操作类型
 *
 * @author mdl
 * @date 2020/4/3 13:24
 */
public enum OpType {

    /**
     * 支付宝支付请求
     */
    AlipayPayment("payment.alipay"),

    /**
     * 微信支付请求
     */
    WechatPayment("payment.wechat");

    private String value;

    OpType(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

}

三、自定义注解

package com.example.demo.factory.annoation;

import com.example.demo.factory.enums.OpType;
import org.springframework.stereotype.Component;

import java.lang.annotation.*;

/**
 * @author mdl
 * @date 2020/4/2 11:01
 */

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Processor {

    /**
     * 可以支持多个操作对应一个实例,看具体情况吧
     *
     * @return
     */
//    OpType[] value();
      OpType value();
}

四、实现类

实现类1

package com.example.demo.factory.service.impl;

import com.example.demo.factory.annoation.Processor;
import com.example.demo.factory.enums.OpType;
import com.example.demo.factory.service.ProcessHandle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 支付宝处理逻辑
 *
 * @author mdl
 * @date 2020/4/3 13:45
 */
@Slf4j
@Service
@Processor(OpType.AlipayPayment)
public class AlipayProcessHandle implements ProcessHandle {
    @Override
    public Object dealProcess(Object obj) {
        log.info("支付宝支付方式处理...");
        return null;
    }
}

实现类2

package com.example.demo.factory.service.impl;

import com.example.demo.factory.annoation.Processor;
import com.example.demo.factory.enums.OpType;
import com.example.demo.factory.service.ProcessHandle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 微信支付处理逻辑
 *
 * @author mdl
 * @date 2020/4/3 13:45
 */
@Slf4j
@Service
@Processor(OpType.WechatPayment)
public class WechatProcessHandle implements ProcessHandle {
    @Override
    public Object dealProcess(Object obj) {
        log.info("微信支付方式处理...");
        return null;
    }
}

五、Controller

package com.example.demo.controller;

import com.example.demo.factory.ProcessorFactory;
import com.example.demo.factory.service.ProcessHandle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author mdl
 * @date 2020/4/3 13:17
 */
@Controller
@Slf4j
public class ExampleController {

    @Autowired
    private ProcessorFactory processorFactory;

    @RequestMapping(value ="/home", method = RequestMethod.GET)
    @ResponseBody
    public String home(){
        return "你好,Spring Boot";
    }

    @RequestMapping(value ="/pay", method = RequestMethod.GET)
    @ResponseBody
    public String pay(@RequestParam("payType") String payType,
                      @RequestParam("params") String params){

        ProcessHandle processHandle = processorFactory.getProcessHandleByKey(payType);
        if(null != processHandle){
            processHandle.dealProcess(params);
        }else{
            log.error("不支持的支付方式,支付参数: " + payType);
        }

        return "你好,Spring Boot";
    }

}

访问:

http://localhost:8080/pay?payType=payment.wechat&params=sss

结果:

 

posted @ 2020-04-03 14:37  饮酒至天明  阅读(727)  评论(0编辑  收藏  举报