Spring系列(七):@FactoryBean注解用法介绍

简介: FactoryBean是实现了FactoryBean<T>接口的Bean,可以该Bean的ID从BeanFactory中获取的实际上是FactoryBean中getObject()方法返回的实例对象,而并不是直接FactoryBean本身,想要获取FactoryBean对象本身,可以在id前面加一个&符号来获取

今天给大家介绍@FactoryBean注解用法,希望对大家能有所帮助!

image_e4095870.png

1、@FactoryBean注解介绍

FactoryBean是实现了FactoryBean接口的Bean,可以该Bean的ID从BeanFactory中获取的实际上是FactoryBean中getObject()方法返回的实例对象,而并不是直接FactoryBean本身,想要获取FactoryBean对象本身,可以在id前面加一个&符号来获取。

BeanFactory部分代码:

说明:String FACTORY\_BEAN\_PREFIX = "&" ,&符号表示要获取FactoryBean本身

package org.springframework.beans.factory;


import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;


public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";}

2、@FactoryBean的源码内容如下:

Spring3.0版本之后,FactoryBean开始支持泛型,即接口声明改为FactoryBean的形式

package org.springframework.beans.factory;


import org.springframework.lang.Nullable;


public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";


    @Nullable
    T getObject() throws Exception;


    @Nullable
    Class<?> getObjectType();


    default boolean isSingleton() {
        return true;
    }
}

实现FactoryBean接口有一下三个方法

  • getObject:获取bean对应的实例对象
  • getObjectType:获取factoryBean获取到的实例类型
  • isSingleton:factoryBean创建的实例是否是单实例

3、用法示例

3.1 新建Book.java

package com.spring.bean;


public class Book {
    private String bookName;
    private String bookType;
    private double price;


    public Book(String bookName, String bookType, double price) {
        this.bookName = bookName;
        this.bookType = bookType;
        this.price = price;
    }


    public String getBookName() {
        return bookName;
    }


    public void setBookName(String bookName) {
        this.bookName = bookName;
    }


    public String getBookType() {
        return bookType;
    }


    public void setBookType(String bookType) {
        this.bookType = bookType;
    }


    public double getPrice() {
        return price;
    }


    public void setPrice(double price) {
        this.price = price;
    }


    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", bookType='" + bookType + '\'' +
                ", price=" + price +
                '}';
    }
}

3.2 新建BookFactoryBean.java

package com.spring.bean;




import org.springframework.beans.factory.FactoryBean;




public class BookFactoryBean implements FactoryBean<Book> {
    public BookFactoryBean factoryBeanVO() {
        return new BookFactoryBean();
    }


    public Book getObject() throws Exception {
        return new Book("红楼梦", "中国名著", 88);
    }


    public Class<?> getObjectType() {
        return Book.class;
    }


    public boolean isSingleton() {
        return true;
    }
}

3.3 FactoryBeanConfig.java

package com.spring.config;

import com.spring.bean.BookFactoryBean;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FactoryBeanConfig  {
    @Bean
    public BookFactoryBean bookFactoryBean()
    {
        return new BookFactoryBean();
    }
}

3.4 TestFactoryBean.java

package com.spring.test;


import com.spring.config.FactoryBeanConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


public class TestFactoryBean {


    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationContext = new AnnotationConfigApplicationContext(FactoryBeanConfig.class);
        // 获取工厂类的bean
        Object bookFactoryBean = annotationContext.getBean("bookFactoryBean");
        System.out.println(bookFactoryBean.getClass());
        // 输出结果:class com.spring.bean.Book
        //获取FactoryBean 本身 加 &符号
        Object bookFactoryBean1 = annotationContext.getBean("&bookFactoryBean");
        System.out.println(bookFactoryBean1.getClass());
        // 输出结果:class com.spring.bean.BookFactoryBean
    }
}

4、@FactoryBean应用场景

  • 单一的对象使用FactoryBean意义不大。
  • 创建对象时需要依赖于需要别的接口来监听数据、根据推送数据过来的接口做一些数据处理。
  • 搭配其他接口协作, 依赖于Spring生命周期, 针对某个时间节点、合适的条件判断,来生成自己需要的对象。

5、典型应用

  • MyBatis3 提供 mybatis-spring项目中的 org.mybatis.spring.SqlSessionFactoryBean:
  • 阿里开源的分布式服务框架 Dubbo 中的Consumer 也使用到了FactoryBean
  • shiro中ShiroFilterFactoryBean
  • druid的JdbcStatManagerFactoryBean
相关文章
|
2月前
|
Java 开发者 Spring
【SpringBoot 异步魔法】@Async 注解:揭秘 SpringBoot 中异步方法的终极奥秘!
【8月更文挑战第25天】异步编程对于提升软件应用的性能至关重要,尤其是在高并发环境下。Spring Boot 通过 `@Async` 注解简化了异步方法的实现。本文详细介绍了 `@Async` 的基本用法及配置步骤,并提供了示例代码展示如何在 Spring Boot 项目中创建与管理异步任务,包括自定义线程池、使用 `CompletableFuture` 处理结果及异常情况,帮助开发者更好地理解和运用这一关键特性。
125 1
|
2月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
2月前
|
缓存 Java 数据库连接
Spring Boot奇迹时刻:@PostConstruct注解如何成为应用初始化的关键先生?
【8月更文挑战第29天】作为一名Java开发工程师,我一直对Spring Boot的便捷性和灵活性着迷。本文将深入探讨@PostConstruct注解在Spring Boot中的应用场景,展示其在资源加载、数据初始化及第三方库初始化等方面的作用。
53 0
|
9天前
|
Java Spring 容器
Spring使用异步注解@Async正确姿势
Spring使用异步注解@Async正确姿势,异步任务,spring boot
|
8天前
|
XML Java 数据格式
spring复习03,注解配置管理bean
Spring框架中使用注解配置管理bean的方法,包括常用注解的标识组件、扫描组件、基于注解的自动装配以及使用注解后的注意事项,并提供了一个基于注解自动装配的完整示例。
spring复习03,注解配置管理bean
|
9天前
|
XML 前端开发 Java
控制spring框架注解介绍
控制spring框架注解介绍
|
22天前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
2月前
|
Java 数据安全/隐私保护 Spring
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
|
2月前
|
XML Java 数据库
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
这篇文章是Spring5框架的实战教程,详细介绍了事务的概念、ACID特性、事务操作的场景,并通过实际的银行转账示例,演示了Spring框架中声明式事务管理的实现,包括使用注解和XML配置两种方式,以及如何配置事务参数来控制事务的行为。
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
|
2月前
|
监控 安全 Java
【开发者必备】Spring Boot中自定义注解与处理器的神奇魔力:一键解锁代码新高度!
【8月更文挑战第29天】本文介绍如何在Spring Boot中利用自定义注解与处理器增强应用功能。通过定义如`@CustomProcessor`注解并结合`BeanPostProcessor`实现特定逻辑处理,如业务逻辑封装、配置管理及元数据分析等,从而提升代码整洁度与可维护性。文章详细展示了从注解定义、处理器编写到实际应用的具体步骤,并提供了实战案例,帮助开发者更好地理解和运用这一强大特性,以实现代码的高效组织与优化。
57 0
下一篇
无影云桌面