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,类似于设计模式中的工厂模式和装饰器模式


目录
相关文章
|
2月前
|
人工智能 前端开发 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应用的开发流程。
900 0
|
2月前
|
XML 前端开发 安全
Spring MVC:深入理解与应用实践
Spring MVC是Spring框架提供的一个用于构建Web应用程序的Model-View-Controller(MVC)实现。它通过分离业务逻辑、数据、显示来组织代码,使得Web应用程序的开发变得更加简洁和高效。本文将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring MVC,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
128 2
|
2月前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
75 14
|
3月前
|
消息中间件 Java Kafka
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
86 1
|
3月前
|
JSON 安全 算法
Spring Boot 应用如何实现 JWT 认证?
Spring Boot 应用如何实现 JWT 认证?
108 8
|
3月前
|
Java Docker 微服务
利用Docker容器化部署Spring Boot应用
利用Docker容器化部署Spring Boot应用
72 0
|
3月前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
406 12
基于开源框架Spring AI Alibaba快速构建Java应用
|
3月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
231 2
|
3月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
170 62
|
4月前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。