文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

spring boot动态生成接口怎么实现

2023-06-21 21:47

关注

本篇内容主要讲解“spring boot动态生成接口怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“spring boot动态生成接口怎么实现”吧!

在某些业务场景中,我们只需要业务代码中定义相应的接口或者相应的注解,并不需要实现对应的逻辑。

比如 mybatis和feign: 在 mybatis 中,我们只需要定义对应的mapper接口;在 feign 中,我们只需要定义对应业务系统中的接口即可。

那么在这种场景下,具体的业务逻辑时怎么执行的呢,其实原理都是动态代理。

我们这里不具体介绍动态代理,主要看一下它在springboot项目中的实际应用,下面我们模仿feign来实现一个调用三方接口的 httpclient。

一: 定义注解

package com.mysgk.blogdemo.annotation;public @interface MyHttpClient {}

二: 建立动态代理类

package com.mysgk.blogdemo.proxy;import org.springframework.beans.factory.FactoryBean;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class RibbonAopProxyFactory<T> implements FactoryBean<T>, InvocationHandler {private Class<T> interfaceClass;public Class<T> getInterfaceClass() {return interfaceClass;}public void setInterfaceClass(Class<T> interfaceClass) {this.interfaceClass = interfaceClass;}@Overridepublic T getObject() throws Exception {return (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{interfaceClass}, this);}@Overridepublic Class<?> getObjectType() {return interfaceClass;}@Overridepublic boolean isSingleton() {return true;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {return "invoke " + proxy.getClass().getName() + "." + method.getName() + " , do anything ..";}}

三: 注入spring容器

package com.mysgk.blogdemo.start;import cn.hutool.core.util.ClassUtil;import cn.hutool.core.util.StrUtil;import com.mysgk.blogdemo.annotation.MyHttpClient;import com.mysgk.blogdemo.proxy.RibbonAopProxyFactory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.beans.factory.support.BeanDefinitionBuilder;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;import org.springframework.beans.factory.support.GenericBeanDefinition;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;import java.util.Set;@Componentpublic class ScanHttpClients implements BeanDefinitionRegistryPostProcessor, ApplicationContextAware {private final Logger logger = LoggerFactory.getLogger(ScanHttpClients.class);private ApplicationContext ctx;public void run(BeanDefinitionRegistry registry) {Set<Class<?>> scanPackage = ClassUtil.scanPackageByAnnotation("com.mysgk", MyHttpClient.class);for (Class<?> cls : scanPackage) {BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(cls);GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();definition.getPropertyValues().add("interfaceClass", definition.getBeanClassName());definition.setBeanClass(RibbonAopProxyFactory.class);definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);String beanName = StrUtil.removePreAndLowerFirst(cls.getSimpleName(), 0) + "RibbonClient";registry.registerBeanDefinition(beanName, definition);}}@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {run(registry);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.ctx = ctx;}}

四: 编写拦截器

package com.mysgk.blogdemo.aop;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpEntity;import org.springframework.http.HttpMethod;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Component;import org.springframework.web.client.RestTemplate;@Component@Aspectpublic class InterceptAnnotation {@Autowiredprivate RestTemplate ribbonLoadBalanced;@Pointcut("@annotation(com.mysgk.blogdemo.annotation.MyHttpClient)")public void execute() {}@Around("execute()")public Object interceptAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {ResponseEntity<?> exchange = ribbonLoadBalanced.exchange("url", HttpMethod.GET, HttpEntity.EMPTY, Object.class);return exchange.getBody();}}

五: 新建测试类

package com.mysgk.blogdemo.client;import com.mysgk.blogdemo.annotation.MyHttpClient;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;@MyHttpClientpublic interface MyHttpClientTest {@PostMapping(value = "test/t1")Object test(String param);}

项目结构:

spring boot动态生成接口怎么实现

到此,相信大家对“spring boot动态生成接口怎么实现”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯