工厂模式创建动态代理实现类

通过工厂,,传入指定的接口类型,,动态代理生成增强的实现类:

用到的例子:

  • langchain4j中AiService,传入指定的接口,创建增强的实现类,通过@SystemMessage @UserMessage 动态组装内容发送给ai
  • Mybatis的mapper,, 也是这种,通过SqlSession.getMapper(接口) ,,解析接口上面的注解,获取动态代理实现类
  • Spring data JPA
  • spring cloud openfeign
简单版

定义一个注解:

java 复制代码
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoMethod {

    String value() default "";
}

接口:

java 复制代码
public interface MessageService {


    @AutoMethod("发送邮件: %s,,内容:%s")
    String sendEmail(String to,String content);

    @AutoMethod("发送sms: %s,,内容:%s")
    String sendSms(String to,String content);
}

定义一个工厂,动态创建这个接口的实现类,,拦截注解:

java 复制代码
public class SimpleServiceFactory {


    public static <T> T create(Class<T> serviceClass){

        return (T) Proxy.newProxyInstance(serviceClass.getClassLoader(), new Class[]{serviceClass}, new SimpleInvocationHandler());

    }


    static class SimpleInvocationHandler implements InvocationHandler{

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

            AutoMethod annotation = method.getAnnotation(AutoMethod.class);
            if (annotation != null){
                String template = annotation.value();
                return String.format(template,args);
            }else{
                return "执行"+method.getName();
            }

        }
    }
}

使用:

java 复制代码
public class Demo01 {

    public static void main(String[] args) {
        MessageService service = SimpleServiceFactory.create(MessageService.class);


        String s = service.sendEmail("xxx@qq.com", "hello");
        System.out.println("s = " + s);


        String s1 = service.sendSms("137090xxx", "hehe123");
        System.out.println("s1 = " + s1);
        
    }

}
增强版

通过拦截注解,,调用不同的实现类

java 复制代码
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MsgHandler {

    // 消息类型
    String type();
    // 执行动作
    String action();

}
java 复制代码
public interface MessageHandler {

    @MsgHandler(type = "email", action = "send")
    void handleEmail(String to, String content);

    @MsgHandler(type = "sms", action = "send")
    void handleSms(String phone, String message);

    @MsgHandler(type = "log", action = "record")
    void logMessage(String message);
}
java 复制代码
/**
 * 消息处理器
 */
public interface MsgProcessor {

    void process(Object[] args);
}
java 复制代码
package com.cj.aikefu.hehe02;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class EnhancedServiceFactory {
    private static final Map<String,MsgProcessor> processors = new HashMap<>();

    static {
        processors.put("email-send",args->{
            System.out.println("email send"+args[0]+args[1]);
        });
        processors.put("sms-send",args -> {
            System.out.println("send sms"+args[0]+args[1]);
        });
    }

    public static <T> T create(Class<T> serviceClass){
       return (T) Proxy.newProxyInstance(serviceClass.getClassLoader(),new Class[]{serviceClass},new EnhancedInvocationHandler());
    }

    static class EnhancedInvocationHandler implements InvocationHandler {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            MsgHandler annotation = method.getAnnotation(MsgHandler.class);
            if (annotation != null){
                String key = annotation.type() + "-" + annotation.action();
                MsgProcessor msgProcessor = processors.get(key);
                if (msgProcessor != null){
                    msgProcessor.process(args);
                }else{
                    System.out.println("未找到处理器"+key);
                }
            }

            return null;
        }
    }

}

测试:

java 复制代码
public class Demo01 {

    public static void main(String[] args) {
        MessageHandler handler = EnhancedServiceFactory.create(MessageHandler.class);
        handler.handleEmail("xxx","hello");
        handler.handleSms("123","hehe123");
    }
}
相关推荐
y = xⁿ3 分钟前
【从零开始学习Redis|第七篇】Redis 进阶原理篇:消息队列、分布式锁、缓存击穿与事务实现
java·redis·学习·缓存
码不停蹄Zzz33 分钟前
C语言【结构体值传递问题】
c语言·开发语言
AMoon丶35 分钟前
Golang--多种数据结构详解
linux·c语言·开发语言·数据结构·c++·后端·golang
wearegogog12338 分钟前
C# Modbus 协议实现
开发语言·c#
深蓝轨迹40 分钟前
SpringBoot YAML配置文件全解析:语法+读取+高级用法
java·spring boot·后端·学习
紫郢剑侠1 小时前
【C语言编程gcc@Kylin | 麒麟 】5:获取系统启动时间
c语言·开发语言·kylin·gcc·麒麟操作系统
深蓝轨迹1 小时前
乐观锁 vs 悲观锁 含面试模板
java·spring boot·笔记·后端·学习·mysql·面试
东离与糖宝1 小时前
AI 智能体安全踩坑记:Java 为 OpenClaw 添加权限控制与审计日志实战
java·人工智能
晓晓hh1 小时前
JavaSe学习——基础
java·开发语言·学习
清水白石0081 小时前
Python 内存陷阱深度解析——浅拷贝、深拷贝与对象复制的正确姿势
开发语言·python