利用自定义注解+Map+反射实现策略模式

该博客介绍了如何在Java中使用策略模式和反射来实现动态加载不同的支付策略。通过自定义注解`PutInMap`标记支付策略类,并在启动时扫描指定包路径,将带有注解的类加载到并发HashMap中。在实际支付过程中,根据支付方式从策略Map中获取并执行相应的支付策略,如微信支付和支付宝支付。这种方式实现了代码的解耦和灵活扩展。
摘要由CSDN通过智能技术生成

场景:TODO

思路:

        1.扫描所有有自定义注解的类通过反射put到map中(初始化类似与IOC启动流程)

        2.根据不同策略从map中获取对应的处理类处理业务

代码实现:

1.自定义注解

/**
 * 标记类需要put到策略map中
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PutInMap {
    // 策略模式名称
    String value() default "";
}

2.决策类

public class StrategyContext02 {
    // 策略Map
    public static final ConcurrentHashMap<String,IPayStrategy02> strategyMap = new ConcurrentHashMap<>();
    // 扫描包路径
    private static final String PACKAGE_NAME = "cn.zk.strategy02";

    /**
     * 根据支付方式进行支付
     * @param payMode
     * @return
     */
    public boolean pay(String payMode) {
        IPayStrategy02 strategy02 = strategyMap.get(payMode);
        return Objects.isNull(strategy02) ? false : strategy02.pay();
    }

    /**
     * 初始化map
     */
    public void initStrategyMap() {
        Reflections reflections = new Reflections(PACKAGE_NAME);
        // 获取所有包含PutInMap注解的类
        Set<Class<?>> annotationClasses = reflections.getTypesAnnotatedWith(PutInMap.class);
        for (Class<?> classObject: annotationClasses) {
            // 将PutInMap的value作为key,IPayStrategy02实现类未value放入map中
            PutInMap annotation = classObject.getAnnotation(PutInMap.class);
            IPayStrategy02 instance = null;
            try {
                 instance = (IPayStrategy02)classObject.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            strategyMap.put(annotation.value(),instance);
            System.out.println("策略Map加入元素"+annotation.value()+"....");
        }
        System.out.println("策略Map初始化完成");
    }

    /**
     * 清理map
     */
    public void clearMap() {
        strategyMap.clear();
    }

}

3.策略接口

/**
 * 支付策略接口
 */
public interface IPayStrategy02 {
    boolean pay();
}

4.具体实现类

        4.1微信支付

/**
 * WxPay
 */
@PutInMap("WxPay")
public class WxPayStrategyImpl implements IPayStrategy02 {
    @Override
    public boolean pay() {
        System.out.println("支付=====>WxPay");
        return true;
    }
}

        4.1阿里支付

/**
 * AliPa
 */
@PutInMap("AliPa")
public class AliPayStrategyImpl implements IPayStrategy02 {
    @Override
    public boolean pay() {
        System.out.println("支付=====>AliPa");
        return true;
    }
}

测试

        1.使用微信支付

        2.使用阿里支付

 

Java注解是一种元数据,它可以为类、方法、字段等元素添加额外的信息。在Java中,可以使用自定义注解反射实现导入导出Excel文档。 首先,定义一个自定义注解,用于标记需要导出的实体类的字段: ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ExcelField { /** * 列名 */ public String name(); /** * 顺序 */ public int order(); } ``` 然后,在实体类的字段上添加该注解: ```java public class User { @ExcelField(name = "姓名", order = 1) private String name; @ExcelField(name = "年龄", order = 2) private int age; // 省略其他字段和方法 } ``` 接着,定义一个工具类,用于读取和写入Excel文档: ```java public class ExcelUtil { /** * 从Excel中读取数据 */ public static <T> List<T> readFromExcel(InputStream is, Class<T> clazz) { List<T> list = new ArrayList<>(); try { Workbook workbook = WorkbookFactory.create(is); Sheet sheet = workbook.getSheetAt(0); Map<Integer, String> headers = getHeaders(sheet.getRow(0)); for (int i = 1; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); T obj = clazz.newInstance(); for (int j = 0; j < row.getLastCellNum(); j++) { Cell cell = row.getCell(j); String value = getValue(cell); String fieldName = headers.get(j); Field field = clazz.getDeclaredField(fieldName); field.setAccessible(true); setValue(obj, field, value); } list.add(obj); } } catch (Exception e) { e.printStackTrace(); } return list; } /** * 写入数据到Excel中 */ public static <T> void writeToExcel(List<T> list, OutputStream os) { try { Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); Row header = sheet.createRow(0); Map<String, Integer> fields = getFields(list.get(0).getClass()); List<String> fieldNames = new ArrayList<>(fields.keySet()); Collections.sort(fieldNames); for (int i = 0; i < fieldNames.size(); i++) { String fieldName = fieldNames.get(i); Cell cell = header.createCell(i); cell.setCellValue(fields.get(fieldName)); } for (int i = 0; i < list.size(); i++) { Row row = sheet.createRow(i + 1); T obj = list.get(i); for (int j = 0; j < fieldNames.size(); j++) { String fieldName = fieldNames.get(j); Field field = obj.getClass().getDeclaredField(fieldName); field.setAccessible(true); Object value = field.get(obj); Cell cell = row.createCell(j); cell.setCellValue(value.toString()); } } workbook.write(os); } catch (Exception e) { e.printStackTrace(); } } /** * 获取Excel中的列名 */ private static Map<Integer, String> getHeaders(Row row) { Map<Integer, String> headers = new HashMap<>(); for (int i = 0; i < row.getLastCellNum(); i++) { Cell cell = row.getCell(i); String value = getValue(cell); headers.put(i, value); } return headers; } /** * 获取实体类中的字段名和顺序 */ private static <T> Map<String, Integer> getFields(Class<T> clazz) { Map<String, Integer> fields = new HashMap<>(); Field[] declaredFields = clazz.getDeclaredFields(); for (Field field : declaredFields) { if (field.isAnnotationPresent(ExcelField.class)) { ExcelField excelField = field.getAnnotation(ExcelField.class); fields.put(field.getName(), excelField.order()); } } return fields; } /** * 设置实体类中的字段值 */ private static <T> void setValue(T obj, Field field, String value) throws Exception { String typeName = field.getType().getName(); if ("int".equals(typeName)) { field.set(obj, Integer.parseInt(value)); } else if ("java.lang.String".equals(typeName)) { field.set(obj, value); } // 省略其他类型的判断 } /** * 获取单元格中的值 */ private static String getValue(Cell cell) { String value = ""; if (cell != null) { switch (cell.getCellType()) { case STRING: value = cell.getStringCellValue(); break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { Date date = cell.getDateCellValue(); value = new SimpleDateFormat("yyyy-MM-dd").format(date); } else { value = String.valueOf(cell.getNumericCellValue()); } break; case BOOLEAN: value = String.valueOf(cell.getBooleanCellValue()); break; case FORMULA: value = String.valueOf(cell.getCellFormula()); break; default: value = ""; } } return value; } } ``` 最后,可以使用该工具类来读取和写入Excel文档: ```java public class Main { public static void main(String[] args) { // 从Excel中读取数据 try (InputStream is = new FileInputStream("users.xlsx")) { List<User> list = ExcelUtil.readFromExcel(is, User.class); for (User user : list) { System.out.println(user.getName() + ", " + user.getAge()); } } catch (Exception e) { e.printStackTrace(); } // 写入数据到Excel中 List<User> list = new ArrayList<>(); list.add(new User("张三", 20)); list.add(new User("李四", 30)); list.add(new User("王五", 40)); try (OutputStream os = new FileOutputStream("users.xlsx")) { ExcelUtil.writeToExcel(list, os); } catch (Exception e) { e.printStackTrace(); } } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值