java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > FactoryBean使用及底层工作原理

FactoryBean的使用及底层工作原理分析

作者:冰点.

FactoryBean接口解析与使用示例,详解Spring框架中FactoryBean的作用和底层原理,以及如何通过FactoryBean实现对象的动态创建is装配is代理is包装和生命周期管理

大家好,我是冰点,本节我们通过对FactoryBean 接口源码解析,以及使用示例剖析,让大家3分钟了解FactoryBean的作用和底层工作原理。以及FactoryBean的使用场景,学以致用。

FactoryBean是Spring框架中的一个接口,用于创建和管理其他Bean实例的对象。

FactoryBean的底层工作原理是通过实现FactoryBean接口并实现其中的方法来创建和管理Bean实例。

1.FactoryBean接口源码解析

public interface FactoryBean<T> {
    
    // 获取由此工厂创建的对象实例
    T getObject() throws Exception;

    // 获取由此工厂创建的对象实例的类型
    Class<?> getObjectType();

    // 判断由此工厂创建的对象实例是否为单例模式
    default boolean isSingleton() {
        return true;
    }
}

2.FactoryBean使用代码示例

一个简单的FactoryBean示例代码,咱们创建一个随机数生成器的实例:

import java.util.Random;
import org.springframework.beans.factory.FactoryBean;

public class RandomNumberFactoryBean implements FactoryBean<Random> {

    private int seed;

    public void setSeed(int seed) {
        this.seed = seed;
    }

    @Override
    public Random getObject() throws Exception {
        return new Random(seed);
    }

    @Override
    public Class<?> getObjectType() {
        return Random.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

要使用注解方式实例化RandomNumberFactoryBean,可以使用@Configuration@Bean注解。

首先,创建一个配置类,使用@Configuration注解标记该类为配置类。然后,在该类中创建一个用于实例化RandomNumberFactoryBean@Bean方法,如下所示:

import java.util.Random;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public RandomNumberFactoryBean myRandom() {
        RandomNumberFactoryBean factoryBean = new RandomNumberFactoryBean();
        factoryBean.setSeed(12345);
        return factoryBean;
    }
}

在这个示例中,AppConfig类使用@Configuration注解标记为配置类。然后,它定义了一个名为myRandom@Bean方法,该方法返回一个RandomNumberFactoryBean实例,并为其设置seed属性值为12345。

最后,在Spring应用程序中,使用AnnotationConfigApplicationContext类来加载该配置类,如下所示:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyApp {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        Random random = context.getBean("myRandom", Random.class);
        int number = random.nextInt();
        System.out.println("Random number: " + number);
        context.close();
    }
}

在这个示例中,MyApp类使用AnnotationConfigApplicationContext类来加载AppConfig配置类,并从容器中获取myRandom Bean实例。然后,它使用该实例生成一个随机数,并将其输出到控制台。

使用注解方式实例化RandomNumberFactoryBean与使用XML配置方式实例化它的区别在于,我们可以在@Bean方法中直接创建RandomNumberFactoryBean实例,并为其设置属性值,而不需要使用XML配置文件。这种方式更加便捷和灵活,可以更方便地进行测试和修改。

3. 核心几个点

4. FactoryBean 到底能干什么

FactoryBean允许我们在创建Bean实例时编写自定义的逻辑,并且可以通过其返回的实际Bean实例类型来实现更精细的依赖注入。同时,Spring框架还提供了一些内置的FactoryBean实现,例如ProxyFactoryBeanJndiObjectFactoryBean,可以帮助我们更方便地创建一些常见的Bean实例。

FactoryBean 是 Spring 框架中的一个接口,它可以创建和管理其他对象的实例。通过实现 FactoryBean 接口,可以自定义对象的创建过程,可以实现一些特殊的功能。

FactoryBean 主要有以下作用:

下面给出几种常见的 FactoryBean 的使用示例:

  1. 动态创建对象
public class MyFactoryBean implements FactoryBean<Object> {
    
    @Override
    public Object getObject() throws Exception {
        // 根据配置或条件动态创建对象
        if (someCondition) {
            return new MyObject();
        } else {
            return new AnotherObject();
        }
    }

    @Override
    public Class<?> getObjectType() {
        // 返回实际创建的对象的类型
        return Object.class;
    }

    @Override
    public boolean isSingleton() {
        // 返回是否为单例对象
        return true;
    }
}
  1. 对象的装配和初始化
public class MyFactoryBean implements FactoryBean<MyObject> {

    private String name;
    private int age;

    @Override
    public MyObject getObject() throws Exception {
        // 创建对象并进行装配和初始化
        MyObject myObject = new MyObject();
        myObject.setName(name);
        myObject.setAge(age);
        return myObject;
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 设置属性值的方法
    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  1. 对象的代理和包装
public class MyFactoryBean implements FactoryBean<MyObject> {

    private MyObject target;

    @Override
    public MyObject getObject() throws Exception {
        // 对目标对象进行代理和包装
        MyObjectProxy proxy = new MyObjectProxy(target);
        return proxy.getProxy();
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 设置目标对象的方法
    public void setTarget(MyObject target) {
        this.target = target;
    }
}
  1. 对象的缓存和复用
public class MyFactoryBean implements FactoryBean<MyObject> {

    private static final Map<String, MyObject> objectCache = new ConcurrentHashMap<>();

    private String key;

    @Override
    public MyObject getObject() throws Exception {
        // 根据 key 从缓存中获取对象,如果不存在则创建并放入缓存
        MyObject myObject = objectCache.get(key);
        if (myObject == null) {
            myObject = new MyObject();
            objectCache.put(key, myObject);
        }
        return myObject;
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 设置 key 值的方法
    public void setKey(String key) {
        this.key = key;
    }
}
  1. 对象的延迟初始化
public class MyFactoryBean implements FactoryBean<MyObject>, InitializingBean {

    private MyObject myObject;

    @Override
    public MyObject getObject() throws Exception {
        return myObject;
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 在初始化时创建对象
    @Override
    public void afterPropertiesSet() throws Exception {
        myObject = new MyObject();
        // 执行初始化操作
        myObject.init();
    }
}
  1. 对象的销毁和资源释放
public class MyFactoryBean implements FactoryBean<MyObject>, DisposableBean {

    private MyObject myObject;

    @Override
    public MyObject getObject() throws Exception {
        return myObject;
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 在销毁时释放资源
    @Override
    public void destroy() throws Exception {
        // 执行销毁操作
        myObject.release();
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文