Annotations way to maintain map
map <channelId, implementation class> annotated by scanning and implementation classes achieve the above comments maintenance value map,
map <paytype, implementation class> map maintained by acquiring all implementations of interfaces and implementation classes inside payType
数据库表
//支付渠道表
渠道Id 渠道名称 折扣
//商品表
商品id 商品名称 商品价格
One. Common interfaces and implementation classes each bank payments
//接口
public interface Strategy {
/**
* @param channelId 通过渠道id拿到折扣
* @param goodsId 通过商品id拿到价格
* @return 返回 折扣 * 价格
*/
BigDecimal calRecharge(Integer channelId,Integer goodsId);
//工商银行支付实现
@Pay(channelId = 1)
public class ICBCBankImpl implements Strategy {
@Override
public BigDecimal calRecharge(Integer channelId, Integer goodsId) {
Channel channel = channelMapper.selectById(channelId);
Goods goods = goodsMapper.selectById(goodsId);
if(channel !=null && goods!= null ){
return goods.getAmout.multiply(channel.getDiscount);
}
return null;
}
}
two. Factory class
Function: 1. Create an object implementation class (using the reflection method)
2. Map configured to maintain a value in the annotations and the annotated map class
public class StrategyFactory {
//1.创建本类实例
private static StrategyFactory strategyFactory = new StrategyFactory();
//2.构造方法私有化private
private StrategyFactory(){
}
//3.对外提供暴露一个获取本类实例的方法
public static StrategyFactory getInstance(){
return strategyFactory;
}
//map (1,“com.ruoyi.web.controller.pay.impl.ICBCBankImpl”)
private static Map<Integer,String> source_map = new HashMap<>();
//通过注解维护map 注解上写的"channelId = 1" 和 所注解的类构成Map
static {
//1.扫描impl包下的所有类
Reflections reflections =new Reflections("com.ruoyi.web.controller.pay.impl");
//2.impl包下类上有pay注解的类
Set<Class<?>> classSet = reflections.getTypeAnnotatedWith(Pay.class);
//3.循环遍历set 放到map里
for(Class clazz: classSet){ //遍历实现类
Pay pay = (Pay) clazz.getAnnotation(Pay.class); //获取实现类上面的注解
source_map.put(pay.channelId(),clazz.getCanonicalName());
}
}
//4.生产方法:根据上文id生产出某个银行支付实现的类
public Strategy create(Integer channelId) throws ClassNotFoundException{{
String str = source_map.get(channelId); //str = "com.ruoyi.web.controller.pay.impl.ICBCBankImpl";
Class clazz = Class.forName(str);
return (Strategy) clazz.newInstance();
}
}
//包扫描依赖 Reflections
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
three. Obtaining context class implementation classes channelId
Function: Create object and calculate the price
- create an object factory class to create objects that are created by the calculation to calculate out
public class Context {
public BigDecimal calRecharge(Integer channelId, Integer goodsId) {
StrategyFactory strategyFactory = StrategyFactory.getInstance();
Strategy strategy = strategyFactory.create(channelId);
return strategy.calRecharge(channelId, goodsId);
}
}
four. Custom annotation class
Function; maintenance factory class map
: 1 add the following annotation class file.
2. implemented plus the above class @Pay (channelId is = 1)
3. factory class map maintained by the annotation
@Target(ElementType.TYPE) //指定注解作用在什么上面。 type类 METHOD方法 field成员变量 PARAMETER参数 CONSTRUCTOR构造方法
@Retention(RetentionPolicy.SOURCE) //指定注解声明周期
public @interface Pay {
int channelId(); //if什么这里就是什么
}
Spring acquisition strategy pattern implementation class vessel maintenance map
1. The common interface and its implementation class
public interface PayService {
public String pay(Double name);
public PayType payType();
}
@Service
public class AliPayServiceImpl implements PayService {
@Override
public PayType payType(){
return PayType.AliPay;
}
@Override
public String pay(Double name) {
System.out.println("支付宝支付。。。。。。。。。。。。。。。。");
return "AliPay";
}
}
@Service
public class WechatPayServiceImpl implements PayService {
@Override
public PayType payType() {
return PayType.WeChatPay;
}
@Override
public String pay(Double name) {
System.out.println("微信支付。。。。。。。。。。。。。。。。");
return "WeChat";
}
}
2. context class
1. maintenance map, depending on the implementation of the class interface and implementation class inside payType
2. acquired corresponding implementation classes
@Component
public class PayServiceUtil implements ApplicationContextAware {
//1.初始化Spring容器对象
private ApplicationContext applicationContext;
//2.获取Springr容器对象
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
//3.声明map
private Map<PayType, PayService> payServiceMap = new HashMap<PayType, PayService>();
/**
* 4.注册所有支付类型(获取所有支付实现类)
*/
@PostConstruct
public void registerAllPayService(){
//payService有几个实现类
Map<String, PayService> payMap = applicationContext.getBeansOfType(PayService.class);
for (PayService payService:payMap.values()){
payServiceMap.put(payService.payType(),payService);
}
}
/**
* 5.根据支付类型选择实现类 (根据支付渠道id选择实现类)
* @param payType
* @return
*/
public PayService getPayServiceBypayType(PayType payType){
return payServiceMap.get(payType);
}
}
3. Controller
@Controller
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String hello(){
return "Hello World!";
}
@ResponseBody
@RequestMapping("/pay")
public String pay(){
ApplicationContext context = SpringUtil.context; //获取Spring容器
PayServiceUtil payServiceUtil = context.getBean(PayServiceUtil.class); //获取上下文
PayService payService1 = payServiceUtil.getPayServiceBypayType(PayType.AliPay); //获取支付宝支付实现类
payService1.pay(152.25);
PayService payService2 = payServiceUtil.getPayServiceBypayType(PayType.WeChatPay); //获取微信支付实现类
payService2.pay(152.25);
return "Hello World222!";
}
}
4.SpringUtil和PayType
//获取Spring容器对象
@Component
public class SpringUtil extends ApplicationObjectSupport {
public static ApplicationContext context;
public static Object getBean(String serviceName){
return context.getBean(serviceName);
}
@Override
protected void initApplicationContext(ApplicationContext context) throws BeansException {
super.initApplicationContext(context);
SpringUtil.context = context;
}
}
//枚举类型:支付种类
public enum PayType {
AliPay,
WeChatPay,
CreditPay;
}