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

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

用到的例子:

  • 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");
    }
}
相关推荐
诙_15 小时前
由C++速通Lua
开发语言·lua
TechWayfarer15 小时前
AI大模型时代:IP数据云如何适配智能体场景需求
开发语言·人工智能·python·网络协议·tcp/ip·langchain
DN金猿15 小时前
spring.cloud.nacos.discovery.server-addr和spring.cloud.nacos.server-addr区别
java·开发语言·nacos·springcloud·sca
Jasmine_llq15 小时前
《B4261 [GESP202503 三级] 2025》
开发语言·c++·算法·条件判断算法·位运算恒等式推导·简单算术运算
海兰15 小时前
【实用应用】React+TypeScript+Next.js博客项目
开发语言·javascript·elasticsearch
wjs202415 小时前
C++ 预处理器
开发语言
lly20240615 小时前
《Foundation 提醒框》
开发语言
~|Bernard|15 小时前
GO语言中哪些类型是可比较类型的(==和!=)
开发语言·后端·golang
ChampaignWolf15 小时前
在 Eclipse 中使用 Tabnine
java·ide·eclipse
Deep-w15 小时前
【MATLAB】基于MATLAB的图像加密传输平台【GUI+源码+项目说明】
开发语言·matlab·密码学