spring温习-FactoryBean应用

简介: 不管是平时,还是面试,现在对于spring的讨论少了很多,不再像刚进入人们视野时,那么抢眼;spring现在更像空气一样,只要是java构建的项目,十之八九都是建立在spring之上,因此不可轻视,温故而知新继《BeanFactory与FactoryBean》之后,再看FactoryBean的应用在上面的文章中指定FactoryBean可以更加灵活的创建Bean,那就从Spring管理Bean方式说起

不管是平时,还是面试,现在对于spring的讨论少了很多,不再像刚进入人们视野时,那么抢眼;spring现在更像空气一样,只要是java构建的项目,十之八九都是建立在spring之上,因此不可轻视,温故而知新

《BeanFactory与FactoryBean》之后,再看FactoryBean的应用

在上面的文章中指定FactoryBean可以更加灵活的创建Bean,那就从Spring管理Bean方式说起

XML配置Bean

这种方式,是最早的,借助XML,spring创建bean,来分离调用方与被调用方

id="helloWorld" class="me.spring.beans.HelloWorld">
     name="name" value="Spring">

但是xml不够简洁,且没有编译时检查等功能

@Component @Service

注解开始流行,spring陆续引入了很多注解,关于Bean的有很多

@Component @Service @Repositiory

Java注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的

这些都是把Bean托管给容器

@Bean

从spring3.0开始,可以使用@Configuration与@Bean组合来创建Bean

此注解相对于@Service更灵活了些,如果一个第三方jar中的类需要托管给spring,是没法在类注明@Service注解的,

当然你可以使用XML来实现,但已经约定大于配置,xml不再推荐

除了突破第三方jar限制外,还有

  • 关注点分离,使用@Bean,可以把Bean的创建全部放到了一个地方,接口及其实现不再与具体框架性代码有任何耦合

FactoryBean

虽然@Bean已经相对@Service很灵活了,但还是需要使用@Bean声明,有一些场景无法应对

比如包装RPC,之前写过《RPC的套路》,其实这儿有点AOP的味道

远程service数量是不定的,不能会每一个service去创建并声明上@Bean

一、创建一个FactoryBean

FactroyBean创建的Bean是getObjectType()返回的类型,怎么动态指定此remoteServer,需要使用BeanDefinitionBuilder

@Slf4j
public class RemoteProxyFactoryBean<T> implements FactoryBean<T> , MethodInterceptor {
    @Setter
    @Getter
    private Class<T> remoteService;
    @Setter
    @Getter
    private String url;
    @Override
    public T getObject() throws Exception {
        T service = ProxyFactory.getProxy(remoteService, this);
        return service;
    }
    @Override
    public Class<T> getObjectType() {
        return remoteService;
    }
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        log.info("RemoteProxyFactoryBean invoke");
        Method method = invocation.getMethod();
        log.info("method:{} invoked",method.getName());
        if (method.getDeclaringClass() == Object.class && method.getName().equals("toString")) { return remoteService.getName() + "@" + System.identityHashCode(remoteService); }
        //远程调用service,可以使用HTTP,也可以是TCP
        StringBuilder sb = new StringBuilder(url);
        sb.append(method.getName());
        sb.append("?var=");
        sb.append(Arrays.toString(invocation.getArguments()));
        log.info("get url:{}",sb.toString());
        return null;
    }
}

二、BeanDefinitionBuilder构建Bean注册spring

使用BeanDefinitionBuilder来构建RemoteProxyFactoryBean的属性,并注册到spring; 注意到上面的RemoteProxyFactoryBean并没有使用@Component托管给spring

private void registeRemoteService() throws IOException {
    SimpleMetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory(this.applicationContext);
    //读取此包下的所有类,进行包装
    Resource[] resources = applicationContext.getResources(resolvePackageToScan("com.jack.remote.service"));
    List<String> classNames = Arrays.stream(resources).map(resource -> {
        MetadataReader metadataReader = null;
        try {
            metadataReader = metadataReaderFactory.getMetadataReader(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return metadataReader.getClassMetadata().getClassName();
    }).collect(Collectors.toList());
    //托管给容器
    classNames.forEach(clazz -> {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(RemoteProxyFactoryBean.class);
        beanDefinitionBuilder.addPropertyValue("remoteService",clazz).addPropertyValue("url","http://remotehost/");
        defaultListableBeanFactory.registerBeanDefinition(clazz+"-proxy",beanDefinitionBuilder.getBeanDefinition());
    });
}

三、装配

对于远程service包下的类,就可以直接使用@Autowired来装配

总结

至此FactoryBean已经完结,对于它的作用已经了解:它是一个能生产或修饰对象生成的工厂Bean,类似于设计模式中的工厂模式和装饰器模式


目录
相关文章
|
23天前
|
人工智能 Java API
Java也能快速搭建AI应用?一文带你玩转Spring AI可落地性
Java语言凭借其成熟的生态与解决方案,特别是通过 Spring AI 框架,正迅速成为 AI 应用开发的新选择。本文将探讨如何利用 Spring AI Alibaba 构建在线聊天 AI 应用,并实现对其性能的全面可观测性。
|
18天前
|
人工智能 Java API
Spring AI与DeepSeek实战一:快速打造智能对话应用
在 AI 技术蓬勃发展的今天,国产大模型DeepSeek凭借其低成本高性能的特点,成为企业智能化转型的热门选择。而Spring AI作为 Java 生态的 AI 集成框架,通过统一API、简化配置等特性,让开发者无需深入底层即可快速调用各类 AI 服务。本文将手把手教你通过spring-ai集成DeepSeek接口实现普通对话与流式对话功能,助力你的Java应用轻松接入 AI 能力!虽然通过Spring AI能够快速完成DeepSeek大模型与。
336 11
|
22天前
|
存储 人工智能 开发框架
Spring AI Alibaba 应用框架挑战赛圆满落幕,恭喜获奖选手
第二届开放原子大赛 Spring AI Alibaba 应用框架挑战赛决赛于 2 月 23 日在北京圆满落幕。
|
18天前
|
人工智能 Java API
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
|
5月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
312 1
|
21天前
|
人工智能 Java API
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
|
4月前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
747 54
基于开源框架Spring AI Alibaba快速构建Java应用
|
3月前
|
人工智能 前端开发 Java
Spring AI Alibaba + 通义千问,开发AI应用如此简单!!!
本文介绍了如何使用Spring AI Alibaba开发一个简单的AI对话应用。通过引入`spring-ai-alibaba-starter`依赖和配置API密钥,结合Spring Boot项目,只需几行代码即可实现与AI模型的交互。具体步骤包括创建Spring Boot项目、编写Controller处理对话请求以及前端页面展示对话内容。此外,文章还介绍了如何通过添加对话记忆功能,使AI能够理解上下文并进行连贯对话。最后,总结了Spring AI为Java开发者带来的便利,简化了AI应用的开发流程。
2406 0
|
4月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
189 62
|
3月前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
81 14