大数跨境
0
0

Spring强大的FactoryBean还能这样用,涨知识

Spring强大的FactoryBean还能这样用,涨知识 Spring全家桶实战案例
2024-07-10
4
导读:Spring强大的FactoryBean还能这样用,涨知识

环境:Spring6.1.7



1. 简介

FactoryBean 接口是 Spring IoC 容器实例化逻辑的一个可插入点。如果你有复杂的初始化代码,而这些代码最好用 Java 而不是冗长的 XML 来表达,那么你可以通过自定义自己的 FactoryBean,在该类中编写复杂的初始化,然后将自定义 FactoryBean 添加到容器中。

FactoryBean<T> 接口提供了三种方法:

  • T getObject()返回该工厂创建的对象的实例。该实例可能是共享的,这取决于该工厂返回的是单体还是原型

  • boolean isSingleton()如果此 FactoryBean 返回单例,则返回 true;否则返回 false。此方法的默认实现返回 true。

  • Class<?> getObjectType()返回 getObject() 方法返回的对象类型,如果事先不知道类型,则返回空值。

FactoryBean接口在Spring框架非多的地方被使用。Spring本身就包含了50多个FactoryBean接口的实现。接下来将详细介绍FactoryBean的详细用法

2. 实战案例

准备基本类

class PersonService {  public void save() {     // TODO     System.out.println("save person...") ;  }}

接下来会基于上面的PersonService类进行FactoryBean各种案例的使用

2.1 简单示例

自定义FactoryBean<PersonService>实现

@Componentpublic class PersonServiceFactoryBean implements FactoryBean<PersonService> {  // 具体的实例  public PersonService getObject() throws Exception {    PersonService ps = new PersonService() ;    return ps ;  }  // 具体的类型  public Class<?> getObjectType() {    return PersonService.class ;  }  // true,返回单例容器中只会有一个PersonService  public boolean isSingleton() {    return true ;  }}

具体使用

// 你可以直接在其它的Bean中注入@Resource    private PersonService personService ;// 你可以通过BeanFactory手动获取private ApplicationContext contet ;PersonService ps = context.getBean(PersonService.class) ;

使用时和普通的Bean的使用方式一致。

2.2 多例&不指定类型

多例

如果你需要每次使用时返回的都是不同的实例对象,那么你可以将isSingleton返回为false。

// 将上面的isSingleton返回为falsepublic boolean isSingleton() {  return false ;}

接下来使用时,不管是在其它组件中进行注入还是通过getBean获取,都能确保在每个组件中使用的都不是同一个实例。

@Componentpublic class PersonController {  @Resource  private PersonService personService ;}@Componentpublic class CommonService {  @Resource  private PersonService personService ;}

上面两个类中注入的PersonService将不是同一个实例,如果你通过getBean获取每次也都不是同一个实例。

不指定类型

如果你将FactoryBean#getObjectType方法返回为null。那么你将无法正确的注入PersonService对象,同时程序将抛出异常

2.3 创建代理

你可以通过FactoryBean创建代理对象借助ProxyFactory。将getObject修改如下

public PersonService getObject() throws Exception {  ProxyFactory factory = new ProxyFactory() ;  factory.setTarget(new PersonService()) ;  factory.addAdvice(new MethodInterceptor() {    @Override    public Object invoke(MethodInvocation invocation) throws Throwable {      System.out.println("before...") ;      return invocation.proceed() ;    }  }) ;  return (PersonService) factory.getProxy() ;}

通过FactoryBean能够非常方便的以编程的方式创建代理对象。

2.4 获取原始FactoryBean

如果你需要获取FactoryBean本身,而非getObjectType类型,那么你可以通过如下方式

// 方式1:直接通过类型获取private ApplicationContext context ;context.getBean(PersonServiceFactoryBean.class) ;// 方式2:通过beanName获取,但是需要添加'&'前缀context.getBean("&psFactoryBean") ;

上面2种方式都能正确的获取原始的FactoryBean对象。

2.5 利用SPI获取对象

Spring为我们提供了ServiceFactoryBean类,通过该类我们能非常方便的获取SPI对象并注册为容器Bean。

@Configurationpublic class AppConfig {  @Bean  public ServiceFactoryBean serviceFactoryBean() {    ServiceFactoryBean fb = new ServiceFactoryBean() ;    // 指定SPI接口类型    fb.setServiceType(DAO.class) ;    return fb ;  }}

接下来你就可以在META-INF/services下建立DAO全限定名的文件

com.pack.bean.create.PersonDAOcom.pack.bean.create.StudentDAO

当在容器中注入DAO时,你将得到这里的第一个PersonDAO实例。

注:如果你要获取所有的DAO对象,那么你可以使用ServiceListFactoryBean

以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏

推荐文章

SpringBoot这几个工具类太有用了

SpringBoot3.2开始Controller参数验证@Validated新功能

强大!SpringBoot通过3种方式实现AOP切面,第三种方式性能极佳

当心!请不要在SpringBoot中再犯这样严重的错误

SpringBoot自带Controller接口监控,赶紧用起来

SpringBoot中Controller接口参数这样处理太优雅了

必须掌握的SpringBoot开发技能

强大!基于SpringBoot实现AOP的动态热插拔功能

OpenFeign新功能,终于支持了这2项功能

这才是SpringBoot统一响应和异常处理的最佳实践

请牢记SpringBoot这7个强大的隐藏Bean

请一定掌握SpringBoot这4个高级开发技巧

SpringBoot3第三方接口调用10种方式,最后一种你肯定没用过

警惕!SpringBoot错误发布事件,造成死锁Deadlock

不知道这些不要说玩转了Controller接口

一文让你彻底搞定Spring Security的基本使用

SpringBoot整合RSocket实时数据通信

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读793
粉丝0
内容832