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

2022-04-07 19:12:11 浏览数 (1)

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

1、@FactoryBean注解介绍

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

BeanFactory部分代码:

说明:String FACTORY_BEAN_PREFIX = "&" ,&符号表示要获取FactoryBean本身

代码语言:javascript复制


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<T>的形式

代码语言:javascript复制
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<T>接口有一下三个方法

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

3、用法示例

3.1 新建Book.java

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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

IT技术分享社区

个人博客网站:https://programmerblog.xyz

0 人点赞