FactoryBean?BeanFactory?Spring中的那些有意思的内容

ylnxwlp 菲比啾比!

BeanFactory和FactoryBean傻傻分不清?

BeanFactory是Spring框架的核心接口之一,它定义了Spring容器的基本行为,负责管理Bean的生命周期、配置元数据和依赖注入。BeanFactory的主要功能包括:

Bean的实例化和管理:BeanFactory负责创建、初始化和管理Bean的生命周期。它会根据配置文件中定义的Bean定义来创建Bean的实例。

依赖注入:BeanFactory负责解决Bean之间的依赖关系,确保每个Bean都能获取它所依赖的其他Bean。

配置元数据的管理:BeanFactory会读取和管理应用程序的配置元数据,通常以XML、注解或Java配置的方式定义Bean及其属性。

延迟初始化:BeanFactory支持延迟初始化,即只有在需要时才创建Bean实例。

AOP支持:BeanFactory支持面向切面编程(AOP),允许在Bean的生命周期中应用切面。

BeanFactory是Spring IOC容器的基础,但它通常不会直接使用,而是通过其更高级的实现来使用,如ApplicationContext。

FactoryBean是一个特殊的Bean,它是一个工厂类的接口,负责创建其他Bean的实例。FactoryBean的主要功能包括:

自定义Bean的创建过程:FactoryBean允许我们自定义Bean的创建逻辑。我们可以编写一个实现FactoryBean接口的类,重写getObject方法,以自定义Bean的创建逻辑。

懒加载:FactoryBean可以控制Bean的懒加载。如果我们的FactoryBean返回一个代理对象,它可以推迟实际Bean的创建,直到被请求时。

Bean的包装:FactoryBean可以用于包装其他Bean。我们可以在FactoryBean中创建一个Bean的代理,以便在Bean的生命周期中添加额外的行为。

处理复杂逻辑:FactoryBean常用于创建复杂的Bean实例,例如连接池、远程服务代理等。它们允许我们在Bean的创建过程中执行复杂的逻辑。

BeanFactory 和 FactoryBean区别

用途:
BeanFactory是Spring IoC容器的核心接口,负责管理Bean的生命周期和依赖注入。
FactoryBean是一个特殊的Bean,充当其他Bean的工厂,用于自定义Bean的创建过程。

创建对象:
BeanFactory负责创建Bean对象。
FactoryBean是一个Bean,它的实例本身是一个工厂,负责创建其他Bean的实例。

自定义性:
BeanFactory通常不需要自定义实现,而是由Spring框架提供的。
FactoryBean需要自定义实现,我们需要编写一个类,实现FactoryBean接口,并重写getObject方法来定义Bean的创建逻辑。

懒加载:
BeanFactory默认支持懒加载,可以配置Bean的延迟初始化。
FactoryBean可以通过返回代理对象来实现懒加载,它控制何时创建实际的Bean实例。

简而言之,BeanFactory是Spring IoC容器的核心接口,负责管理Bean的生命周期和依赖注入,大多数的Bean对象,包括Spring中内置的Bean对象和应用程序自定义的Bean对象,都是由BeanFactory创建。而FactoryBean是一个特殊的Bean,它充当其他Bean的工厂,用于自定义Bean的创建过程,支持懒加载、包装和代理,以及处理复杂的逻辑。

Bean可以由两种不同的方式创建:

由BeanFactory创建:大多数Bean是由Spring的BeanFactory或ApplicationContext容器直接创建的,这些Bean是普通的Java对象,不需要实现FactoryBean接口。当我们在Spring配置中定义一个Bean时,通常是直接指定该Bean的类,并且Spring容器会根据类的信息来实例化和管理Bean的生命周期。这些Bean不需要实现FactoryBean接口。

由FactoryBean创建:有些特殊类型的Bean是由实现了FactoryBean接口的类创建的。FactoryBean是一种用于创建其他Bean的工厂,它允许自定义Bean的创建过程。这些FactoryBean实现类实现了FactoryBean接口,重写了getObject方法,用于定义Bean的创建逻辑。

BeanDefinitionRegistryPostProcessor是什么?

BeanDefinitionRegistryPostProcessor是Spring框架中的一个扩展接口,用于在Spring容器加载bean定义(BeanDefinition)之后、但在所有常规的BeanFactoryPostProcessor执行之前,对bean定义注册表(BeanDefinitionRegistry)进行进一步的修改或注册额外的bean定义

接口定义如下:

1
2
3
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

新增了一个方法postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry),可以动态注册bean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 动态注册一个bean
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MyService.class);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
registry.registerBeanDefinition("myDynamicService", beanDefinition);
System.out.println("动态注册了bean: myDynamicService");
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 可进行进一步处理
System.out.println("BeanFactory 后处理");
}
}

BeanFactoryPostProcessor又是什么?

用于在Spring容器实例化任何bean之前,对bean的定义(BeanDefinition)进行修改或处理

1
2
3
4
5
6
7
8
9
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition bd = beanFactory.getBeanDefinition("userService");
bd.setLazyInit(true); // 设置为懒加载
bd.getPropertyValues().add("defaultRole", "USER"); // 添加默认属性
}
}

ImportBeanDefinitionRegistrar是做什么工作的?

ImportBeanDefinitionRegistrar主要用于在Spring容器启动过程中动态地向容器中注册Bean定义(BeanDefinition)。通常配合@Import注解一起使用。

1
2
3
4
@Configuration
@Import(MyImportBeanDefinitionRegistrar.class)
public class AppConfig {
}

接口的定义是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface ImportBeanDefinitionRegistrar {
default void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
}

default void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
registerBeanDefinitions(importingClassMetadata, registry);
}
}

importingClassMetadata:表示使用@Import的那个配置类的元数据(如类名、注解信息等)。

registry:用于注册BeanDefinition的注册表。

Bean是线程安全的吗?

当然不是。如果这个bean中有成员变量,在读写的时候就会发生线程不安全的问题。

解决方法也有很多,比如ThreadLocal,变量放入方法,多例bean,加锁等等。

BeanDefinition的注册顺序由什么来决定?

主要是由注解(配置)的解析顺序来决定:

1、@Configuration
2、@Component
3、@Import:导入普通类
4、@Bean
5、@Import—导入的是实现了ImportBeanDefinitionRegistrar的类
6、BeanDefinitionRegistryPostProcessor

AOP在Spring内的具体实现是怎么样的?仅是动态代理吗

Aop的实现大致分为三大步:

JavaConfig当@EnableAspectJAutoProxy 会通过@Import注册一个BeanPostProcessor处理AOP

解析切面:在Bean创建之前的第一个Bean后置处理器会去解析切面(解析切面中通知、切入点,一个通知就会解析成一个advisor(通知、切入点))

创建动态代理:正常的Bean初始化后调用BeanPostProcessor拿到之前缓存的advisor,再通过advisor中pointcut判断当前Bean是否被切入点表达式匹配,如果匹配,就会为Bean创建动态代理(创建方式1.jdk动态代理2.cglib)。

调用:拿到动态代理对象,调用方法就会判断当前方法是否增强的方法,就会通过调用链的方式依次去执行通知。

Spring AOP和AspectJ的AOP有什么区别?

我们常常在我们想要使用Spring AOP的时候,会去引入一个依赖:AspectJ。这个包为什么要引入呢?

实际上,AspectJ这个的代理和AOP代理不一样,他是属于静态代理,也就是编译时织入。这样一来,AspectJ的性能就会非常好,因为运行的时候就会没有额外开销。所以AspectJ是一种完全的AOP编程解决方案。

但SpringAOP就不一样了,他不会去追求完整的解决方案;而是致力于企业级开发最普遍的需求。所以,SpringAOP仅仅只是使用到了AspectJ里面的切点切面表达式的解析和匹配,并生成动态代理。但也因为这样,Spring AOP的性能也会比较差一些。

  • 标题: FactoryBean?BeanFactory?Spring中的那些有意思的内容
  • 作者: ylnxwlp
  • 创建于 : 2025-10-04 22:19:59
  • 更新于 : 2025-10-26 16:16:30
  • 链接: https://www.swissroll.today/2025/10/04/FactoryBean?BeanFactory?Spring中的那些有意思的内容/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论