大家好,我是冰点,本节我们通过对
FactoryBean
接口源码解析,以及使用示例剖析,让大家3分钟了解FactoryBean的作用和底层工作原理。以及FactoryBean的使用场景,学以致用。
FactoryBean
是Spring框架中的一个接口,用于创建和管理其他Bean实例的对象。FactoryBean
的底层工作原理是通过实现FactoryBean
接口并实现其中的方法来创建和管理Bean实例。
以下是FactoryBean
的代码注释和解释:
1. FactoryBean
接口源码解析
public interface FactoryBean<T> {
// 获取由此工厂创建的对象实例
T getObject() throws Exception;
// 获取由此工厂创建的对象实例的类型
Class<?> getObjectType();
// 判断由此工厂创建的对象实例是否为单例模式
default boolean isSingleton() {
return true;
}
}
getObject()
方法:获取由此工厂创建的对象实例,可以在此方法中编写自定义的创建逻辑,例如从外部资源获取对象实例。getObjectType()
方法:获取由此工厂创建的对象实例的类型,Spring框架可以利用此方法来确定依赖注入时需要注入的具体类型。isSingleton()
方法:判断由此工厂创建的对象实例是否为单例模式。默认情况下,FactoryBean
创建的对象实例是单例模式,但是可以通过覆盖此方法来改变对象实例的作用域。
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实现了FactoryBean接口,并实现了getObject()、getObjectType()和isSingleton()方法。
- 在getObject()方法中,它返回了一个由seed属性指定的随机数生成器的实例。在getObjectType()方法中,它返回了该实例的类型,即Random类。在isSingleton()方法中,它指定了该实例是一个单例模式的Bean。
要使用注解方式实例化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. 核心几个点
当Spring容器启动时,它会扫描应用程序中的所有Bean定义,并实例化那些需要实例化的Bean。如果遇到实现了
FactoryBean
接口的Bean定义,Spring将会为该Bean创建一个特殊的代理对象,以便在需要时调用FactoryBean
的方法来创建实际的Bean实例。当需要使用由
FactoryBean
创建的Bean时,Spring将会调用代理对象的getObject()
方法来获取实际的Bean实例。如果需要,Spring还可以调用代理对象的getObjectType()
方法来确定实际Bean实例的类型。如果
FactoryBean
创建的Bean是单例模式,那么Spring将在第一次调用getObject()
方法时创建实例,并将其缓存起来。以后每次调用getObject()
方法时,都会返回同一个实例。如果FactoryBean
创建的Bean不是单例模式,则每次调用getObject()
方法时都会创建一个新的实例。
4. FactoryBean 到底能干什么
FactoryBean
允许我们在创建Bean实例时编写自定义的逻辑,并且可以通过其返回的实际Bean实例类型来实现更精细的依赖注入。同时,Spring框架还提供了一些内置的FactoryBean
实现,例如ProxyFactoryBean
和JndiObjectFactoryBean
,可以帮助我们更方便地创建一些常见的Bean实例。
基本上三分钟差不多了,希望对大家有所帮助,如果有问题可以评论区或者私信留言。以上就是今天总结的所有内容,谢谢大家阅读。