目录
BeanFactory
是容器,管理所有Bean(包括FactoryBean
),FactoryBean
是被管理的Bean,只是它有特殊能力可以创建其他Bean。
Spring-core里面的ioc容器是通过BeanFactory和applicationContext来实现的,具体可参考:
Spring的核心模块原理介绍_spring 原理-CSDN博客
1、Spring-core
Spring Core容器是Spring框架的核心模块,负责管理应用程序的配置和依赖关系,并通过**控制反转(IoC)和依赖注入(DI)**实现对象的创建、配置和生命周期管理。
如下图所示:
关于spring-core组件和spring-beans及spring-context的联系如下图所示:
2、控制反转(IoC)
2.1、定义
IoC是Spring的核心思想,即对象的创建和依赖关系的管理由Spring容器(而非硬编码)完成。容器接管了对象生命周期的控制权。
2.2、实现方式
通过BeanFactory或ApplicationContext容器来管理Bean,通俗来讲就是工厂和反射来进行实现。
1、BeanFactory
-
定义
BeanFactory
接口体系
关于BeanFactory位于org.springframework.beans.factory包下;
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 = "&";
Object getBean(String name) throws BeansException;
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
*******
}
代码示例如下:
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class BeanFactoryExample {
public static void main(String[] args) {
// 1. 创建资源对象,指定配置文件位置
ClassPathResource resource = new ClassPathResource("beans.xml");
// 2. 创建BeanFactory容器
BeanFactory factory = new XmlBeanFactory(resource);
// 3. 从容器中获取bean (懒加载,此时才会真正创建UserService实例)
UserService userService = (UserService) factory.getBean("userService");
// 4. 使用bean
userService.sayHello();
}
}
// 简单的服务类
class UserService {
public void sayHello() {
System.out.println("Hello from UserService!");
}
}
对应的 beans.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.example.UserService"/>
</beans>
2、ApplicationContext
使用xml文件读取bean的属性。
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ApplicationContextExample {
public static void main(String[] args) {
// 1. 创建ApplicationContext容器 (立即加载并初始化所有单例bean)
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
// 2. 从容器中获取bean
UserService userService = context.getBean("userService", UserService.class);
// 3. 使用bean
userService.sayHello();
// 4. 关闭容器(某些实现类需要)
((ClassPathXmlApplicationContext) context).close();
}
}
// 或者使用注解配置方式
// 或者使用注解配置方式
public class AnnotationConfigExample {
public static void main(String[] args) {
// 1. 创建基于注解的ApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// 2. 获取bean
UserService userService = context.getBean(UserService.class);
// 3. 使用bean
userService.sayHello();
}
}
// 配置类
@Configuration
class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
3、FactoryBean
FactoryBean
是一个接口,定义在org.springframework.beans.factory
包中:
SqlSessionFactoryBean是一个FactoryBean。
// 获取的是SqlSessionFactory对象(由FactoryBean创建)
SqlSessionFactory sessionFactory = context.getBean("sqlSessionFactory");
// 获取FactoryBean本身(很少需要这样用)
SqlSessionFactoryBean factoryBean =
(SqlSessionFactoryBean) context.getBean("&sqlSessionFactory");
代码示例:
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
// 返回由FactoryBean创建的对象实例
T getObject() throws Exception;
// 返回创建对象的类型
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
通过实现这个FactoryBean可以产出任意bean对象,返回的是getObject()方法返回的对象类型。
如下所示:
public class FactoryBeanTest implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new User();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
注意:
如果要实现FactoryBeanTest 本身,可以context.getBean("&FactoryBeanTest")在获取的时候,通过&字符来实现,同时,这个也是懒加载模式。
小结
FactoryBean
是 Spring 中一个强大的扩展点:
-
用于封装复杂对象的创建过程
-
在框架集成中广泛使用(如 MyBatis, Hibernate 等)
-
可以动态决定返回的对象类型
-
通过
&
前缀可以获取 FactoryBean 本身
理解
FactoryBean
的工作机制有助于更深入地掌握 Spring 容器的扩展方式,也能更好地使用各种与 Spring 集成的第三方框架。
总结
理解这两个概念的关键:
-
BeanFactory 是容器本身,是管理所有Bean的"大管家"
-
FactoryBean 是被管理的特殊Bean,是能够生产其他Bean的"小工厂"
-
所有
FactoryBean
都由BeanFactory
管理,而BeanFactory
可以管理各种类型的Bean
这种设计体现了Spring框架的扩展性和灵活性,通过
FactoryBean
机制可以方便地集成各种复杂的第三方库和框架。