天天看點

設計模式 | 工廠模式 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

結果:

設計模式 | 工廠模式 spring boot demo

每一步腳印都要紮得深一點!