设计模式 | 工厂模式 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¶ms=sss
结果:
每一步脚印都要扎得深一点!