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

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

用到的例子:

  • 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");
    }
}
相关推荐
Flittly7 小时前
【AgentScope Java新手村系列】(16)从RAG到多路检索
java·spring boot·spring
小兔崽子去哪了7 小时前
Java 生成二维码解决方案
java·后端
人活一口气12 小时前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
NE_STOP13 小时前
Vibe Coding -- 完整项目案例实操
java
荣码13 小时前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python
SimonKing13 小时前
Google第三方授权登录
java·后端·程序员
明月光81813 小时前
从一行 @Builder 说起:重新拾起 Java 的 Lombok、注解与 Builder 模式
java
考虑考虑1 天前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯1 天前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路1 天前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java