优点:

未使用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. WPF中常用控件(TreeView, ComboBox, DataGrid, ListView)使用MVVM模式绑定的demo

    之前几篇关于TreeView的博客中只是贴了源代码,并没有把整个项目上传到github.最近就想着把我常用的几个控件做成一个demo,这样也方便自己以后查看.本人也是WPF新手,但是我并没有打算就往这 ...

  2. 3D打印第二弹:狗牌

    给朋友做一个狗牌(误,给朋友的狗狗做一个狗牌 1. 设计 没有设计功底,看看别人是如何做的,搜到一个狗牌: 照着这个做一个,正面是上图这种的:狗狗名字+狗爪子:另一面是手机号加联系说明文字. 2. 建 ...

  3. python3中map()函数用法

    python源码解释如下:map(func, *iterables) --> map objectMake an iterator that computes the function usin ...

  4. 别再问WiFi密码了,HMS Core统一扫码服务让手机一键联网

    现代生活离不开网络.在餐厅.商场等公共场所,手机连接WiFi一直是高频使用场景.虽然公共场所的免费WiFi越来越多,但网络连接过程却很麻烦.有的需要打开网页注册或点击广告链接才能上网,还有的要求下载特 ...

  5. Linux 磁盘inode字节数占满的问题

    查看ext系列文件系统的信息 #dumpe2fs /dev/sdc1 Inode count: 65536 inode号数量 Block count: 262144 块数量 Reserved bloc ...

  6. phpStudy 升级 MySQL5.7

    最新在开发项目中需要使用到mysql5.7以上版本,但是phpStudy的版本是5.5,所以需要针对MySQL升级一下 步骤  1.备份原本MySQL 备份:原本phpStudy中的MySQL文件夹改 ...

  7. Java入土---Java运行机制及IDEA的安装使用

    Java运行机制及IDEA的安装使用 java程序运行机制 计算机高级语言分为编译型语言跟解释型语言,而java同时具有两者的特点. 可能对于新手来说,什么是编译,什么是解释; 简单来说,编译就是将代 ...

  8. LGP4001题解

    题目大意 给定一张无向图,需要消耗代价才能使一条边被[数据删除],求使这张图不连通的最小代价. 一看就是最小割的应用啊... 从 \(u\) 到 \(v\),边权为 \(w\) 的边,建两条:一条从 ...

  9. MySQL8.0降级安装5.7

    本文旨在自我学习使用,如有任何疑问请及时联系博主 前言 基于OpenHarmony的FA数字管家服务端 默认情况下,Ubuntu20.04安装MySQL的版本为8.0.但8.0更加严格的加密规则,使得 ...

  10. LintCode 练习题

    /** * 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: 1->2->3->4->5->NULL, k = 2 输 ...