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

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

用到的例子:

  • 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");
    }
}
相关推荐
SL_staff7 分钟前
制造业订单交付崩盘?用四层协同框架重建交付可信度(技术实践)
java·产品·全栈
AI源码17 分钟前
基于 Python 的短视频用户行为分析系统
开发语言·python
旖旎夜光1 小时前
【C++ 基础入门】类和对象(上):封装、对象模型与 this 指针
开发语言·c++·笔记·学习
SL_staff1 小时前
打破风控迭代死循环:用决策编排重构业务与技术协作链路
java·产品·全栈
揽星河..1 小时前
【C语言】结构体
c语言·开发语言
2601_966949651 小时前
如何封装 qd.klines.batch(),让批量 K 线查询函数在多个策略中复用?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
Mikko71 小时前
Redis 连接数满了服务端有错误信息吗?连接数不增加却命令超时?6.2 实测连接池、超时与大 key 怎么判定
java·spring boot·redis·后端
.Bryce.2 小时前
从零到一开发技术名词大全:从需求分析到 AI Agent 工程
java·网络·人工智能·agent·需求分析·agent评测
SL_staff2 小时前
JVS-APS的7个刚性约束设计:从无限产能幻觉到可执行排产的工程实践
java·spring cloud·全栈
神仙别闹3 小时前
基于Python实现英词语自动对齐系统
开发语言·python