优点:

未使用if else,就算以后增加支付类型,也不用改动之前代码

只需要新写一个支付类,给添加自定义注解@Pay

首先:

定义自定义注解 Pay

定义 CMBPay ICBCPay 两种支付 根据注解中的value 标识是哪种支付(1为CMBPay  2为ICBCPay)

两种支付都需继承InitNewService.java 避免注入对象报错

package com.huarui.inter;

import java.math.BigDecimal;

/**
* 支付需实现该接口
* 接口编程:
*/
public interface Strategy { /**
* 计算支付金额 通过渠道id和商品id 进行价格计算
* @param channelId
* @param goodsId
* @return
*/
BigDecimal calRecharge(Integer channelId,Integer goodsId); }
package com.huarui.pay;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.TYPE) //注解定义到类上
@Retention(RetentionPolicy.RUNTIME) //生命周期
public @interface Pay { int value(); }
@Pay(2)
public class ICBCPay extends InitNewService implements Strategy { @Override
public BigDecimal calRecharge(Integer channelId, Integer goodsId) {
//通过渠道id查询优惠折扣 //通过商品id查询商品价格 //返回商品最终价格
return new BigDecimal(100);
}
}

ICBCPay.java

package com.huarui.pay;

import com.huarui.inter.Strategy;
import com.huarui.util.CommonUtil;
import com.huarui.util.InitNewService;
import org.springframework.beans.factory.annotation.Autowired; import java.math.BigDecimal; @Pay(1)
public class CMBPay extends InitNewService implements Strategy { @Autowired
private CommonUtil commonUtil; @Override
public BigDecimal calRecharge(Integer channelId, Integer goodsId) {
//通过渠道id查询优惠折扣 //通过商品id查询商品价格 System.out.println(commonUtil.injectStr()); //返回商品最终价格
return new BigDecimal(100);
}
}

CMBPay.java

package com.huarui.factory;

import com.huarui.inter.Strategy;
import com.huarui.pay.Pay;
import org.reflections.Reflections; import java.util.HashMap;
import java.util.Set; /**
* 【工厂类】
* 通过指定扫码路径读取带有自定义注解Pay的类
* <br>并将全类名保存至map中,格式为["pay的value":"类的全类名"]
* <br> 定义了creator方法,传入支付类型 返回 指定支付对象
*/
public class StrategyFactory { private static StrategyFactory factory = new StrategyFactory(); /**
* 单例
* @return
*/
public static StrategyFactory getInstance(){
return factory;
} public static HashMap<Integer,String> sourceMap = new HashMap<>(); static { //反射工具包,指明扫描路径
Reflections reflections = new Reflections("com.huarui.pay");
//获取带我们pay注解的类
Set<Class<?>> classSet = reflections.getTypesAnnotatedWith(Pay.class);
//根据注解的值,将全类名放到map中
for (Class clazz : classSet){
Pay pay = (Pay) clazz.getAnnotation(Pay.class);
sourceMap.put(pay.value(),clazz.getCanonicalName());
} } public Strategy creator(int type) throws Exception {
//取得全类名
String className = sourceMap.get(type);
//取得类对象
Class clazz= Class.forName(className);
//反射创建对象
return (Strategy) clazz.newInstance();
} }
package com.huarui.inter;

import com.huarui.factory.StrategyFactory;

import java.math.BigDecimal;

public class Context {

    /**
*
* @param channelId 支付类型id
* @param goodsId 商品id
* @return
* @throws Exception
*/
public BigDecimal calRecharge(Integer channelId,Integer goodsId) throws Exception {
Strategy strategy = StrategyFactory.getInstance().creator(channelId);
return strategy.calRecharge(channelId,goodsId);
}
}

junit测试类

package com.huarui;

import com.huarui.inter.Context;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.math.BigDecimal; @RunWith(SpringRunner.class)
@SpringBootTest
public class SbCodeApplicationTests { @Test
public void contextLoads() throws Exception { Context context = new Context();
BigDecimal bigDecimal = context.calRecharge(1,500);
System.out.println(bigDecimal); } }

项目结构:

源码地址: https://github.com/youxiu326/sb_code

springboot使用自定义注解和反射实现一个简单的支付的更多相关文章

  1. java使用注解和反射打造一个简单的jdbc工具类

    a simple jdbc tools 如有转载和引用,请注明出处,谢谢 1. 定义我们需要的注解 要想实现对数据库的操作,我们必须知道数据表名以及表中的字段名称以及类型,正如hibernate 使用 ...

  2. javase基础回顾(四) 自定义注解与反射

    本篇文章将从元注解.自定义注解的格式.自定义注解与反射结合的简单范例.以及自定义注解的应用来说一说java中的自定义注解. 一.元注解 元注解也就是注解其他注解(自定义注解)的java原生的注解,Ja ...

  3. Java利用自定义注解、反射实现简单BaseDao

    在常见的ORM框架中,大都提供了使用注解方式来实现entity与数据库的映射,这里简单地使用自定义注解与反射来生成可执行的sql语句. 这是整体的目录结构,本来是为复习注解建立的项目^.^ 好的,首先 ...

  4. 【Java】利用注解和反射实现一个"低配版"的依赖注入

    在Spring中,我们可以通过 @Autowired注解的方式为一个方法中注入参数,那么这种方法背后到底发生了什么呢,这篇文章将讲述如何用Java的注解和反射实现一个“低配版”的依赖注入. 下面是我们 ...

  5. Android中的自定义注解(反射实现-运行时注解)

    预备知识: Java注解基础 Java反射原理 Java动态代理 一.布局文件的注解 我们在Android开发的时候,总是会写到setContentView方法,为了避免每次都写重复的代码,我们需要使 ...

  6. JAVA-注解(2)-自定义注解及反射注解

    自定义注解开发 1.开发一个注解类 开发一个注解类的过程,非常类似于开发一个接口,只不过需要通过@interface关键字来声明 2.使用元注解修饰注解的声明 所谓的原注解是用来修饰注解声明的注释,可 ...

  7. Springboot使用自定义注解实现简单参数加密解密(注解+HandlerMethodArgumentResolver)

    前言 我黄汉三又回来了,快半年没更新博客了,这半年来的经历实属不易,疫情当头,本人实习的公司没有跟员工共患难, 直接辞掉了很多人.作为一个实习生,本人也被无情开除了.所以本人又得重新准备找工作了. 算 ...

  8. Springboot+Redisson自定义注解一次解决重复提交问题(含源码)

    前言   项目中经常会出现重复提交的问题,而接口幂等性也一直以来是做任何项目都要关注的疑难点,网上可以查到非常多的方案,我归纳了几点如下:   1).数据库层面,对责任字段设置唯一索引,这是最直接有效 ...

  9. SpringBoot:自定义注解实现后台接收Json参数

    0.需求 在实际的开发过程中,服务间调用一般使用Json传参的模式,SpringBoot项目无法使用@RequestParam接收Json传参 只有@RequestBody支持Json,但是每次为了一 ...

随机推荐

  1. C# typeof() 和object.GetType() 、Type..GetType()使用和区别

    进行学习到表达树了,用动Tpye了.所以整理了以下他们区别和用法 总得来说他们都是为了获取某个实例具体引用的数据类型System.Type.1.GetType()方法继承自Object,所以C#中任何 ...

  2. 范围运算符和索引的最终运算符 ^ 在string 和数组中的应用

    //范围运算符在string 和数组中的应用 static void Main(string[] args) { string examplestring = "123456789" ...

  3. 爬虫之爬取B站视频及破解知乎登录方法(进阶)

    今日内容概要 爬虫思路之破解知乎登录 爬虫思路之破解红薯网小说 爬取b站视频 Xpath选择器 MongoDB数据库 爬取b站视频 """ 爬取大的视频网站资源的时候,一 ...

  4. WARN node unsupported "node@v6.11.2" is ......(windows系统更新node版本)

    问题: 使用npm下载文件时报错:WARN node unsupported "node@v6.11.2" is incompatible with electron@^7.1.9 ...

  5. 『现学现忘』Docker相关概念 — 1、云计算概念

    目录 1.云计算的概念 2.示例说明云计算 3.小故事说明云计算 "云计算"这个词,相信大家都非常熟悉. 作为信息科技发展的主流趋势,它频繁地出现在我们的眼前.伴随它一起出现的,还 ...

  6. Linux CentOS7.X-安装mysql5.7数据库(安装包tar.gz)

    一.下载对应版本的mysql 1.官网下载压缩安装包. 进入到mysql官网下载自己对应版本的mysql,下载地址:https://dev.mysql.com/downloads/mysql/5.7. ...

  7. linux作业--第七周

    1.解决DOS攻击生产案例:根据web日志或者或者网络连接数,监控当某个IP 并发连接数或者短时内PV达到100,即调用防火墙命令封掉对应的IP,监控频率每隔5分钟.防火墙命令为:iptables - ...

  8. es6 快速入门 系列 —— 对象

    其他章节请看: es6 快速入门 系列 对象 试图解决的问题 写法繁杂 属性初始值需要重复写 function createPeople(name, age){ // name 和 age 都写了 2 ...

  9. Debian11系统安装

    镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 1. 启动镜像 启动镜像,进入安装界面,默认选择第一个图形化安装界面,回车 2. 选择语言 这里选择English语言,然后点击Continue ...

  10. Arcmap软件报错:This application cannot run under a virtual machine arcmapr, 但是你并没有使用虚拟机

    在任务栏搜索"启用或关闭 windows 功能",取消 "适用于 Linux 的 Windows 子系统" (有可能还需要 取消 "虚拟机平台&quo ...