Spring实例化bean的6种常见方式详解
作者:xiaoye3708
Spring 实例化 Bean 是 IoC 容器的核心能力之一,主要有 6 种常见方式,我会从新手易懂的角度,由基础到进阶逐一讲解,并配合代码示例,让你清晰理解每种方式的使用场景和实现逻辑。
一、核心实例化方式(附代码示例)
1. 构造器实例化(最常用)
这是 Spring 默认的实例化方式,IoC 容器通过调用 Bean 的无参构造器创建实例(如果有参构造器,需通过配置指定参数)。
适用场景:绝大多数普通业务 Bean(如 Service、Controller)。
代码示例:
// 1. 定义普通类(无参构造器默认存在,无需显式写)
public class UserService {
public UserService() {
System.out.println("UserService 无参构造器执行");
}
public void sayHello() {
System.out.println("Hello, Spring!");
}
}
// 2. Spring 配置(XML 方式)
<!-- applicationContext.xml -->
<bean id="userService" class="com.example.UserService"/>
// 3. 测试代码
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) context.getBean("userService");
userService.sayHello(); // 输出:UserService 无参构造器执行 + Hello, Spring!
}
}
如果是有参构造器,XML 配置需指定参数:
xml
<!-- 有参构造器实例化 -->
<bean id="userService" class="com.example.UserService">
<constructor-arg value="张三"/> <!-- 对应构造器的参数 -->
</bean>2. 静态工厂方法实例化
通过调用静态方法返回 Bean 实例,适用于需要统一控制实例创建逻辑的场景(如工具类、单例对象)。
适用场景:第三方类库、自定义单例工厂。
代码示例:
// 1. 定义工厂类(包含静态方法)
public class UserServiceFactory {
// 静态工厂方法,返回 UserService 实例
public static UserService createUserService() {
return new UserService();
}
}
// 2. Spring 配置
<bean id="userService" class="com.example.UserServiceFactory"
factory-method="createUserService"/> <!-- 指定静态工厂方法 -->
// 3. 测试(和构造器方式一致,Spring 会调用 createUserService() 创建实例)
3. 实例工厂方法实例化
通过调用非静态方法(即先创建工厂 Bean 实例,再调用其方法)返回 Bean 实例,适用于工厂类需要维护状态的场景。
适用场景:工厂类需要依赖其他 Bean、或需要多实例工厂。
代码示例:
// 1. 定义实例工厂类(非静态方法)
public class UserServiceInstanceFactory {
public UserService createUserService() {
return new UserService();
}
}
// 2. Spring 配置(先定义工厂 Bean,再通过工厂 Bean 调用方法)
<bean id="userServiceFactory" class="com.example.UserServiceInstanceFactory"/>
<bean id="userService" factory-bean="userServiceFactory"
factory-method="createUserService"/>
4. FactoryBean 接口实例化(进阶)
这是 Spring 提供的专用工厂接口(注意和上面的 “工厂方法” 区分),实现该接口可以自定义 Bean 的创建逻辑,还能控制 Bean 的初始化、销毁。
核心方法:
getObject():返回 Bean 实例;getObjectType():返回 Bean 的类型;isSingleton():是否单例(默认 true)。
适用场景:复杂对象创建(如数据源、MyBatis 的 SqlSessionFactory)。
代码示例:
// 1. 实现 FactoryBean 接口
public class UserServiceFactoryBean implements FactoryBean<UserService> {
@Override
public UserService getObject() throws Exception {
return new UserService(); // 自定义创建逻辑
}
@Override
public Class<?> getObjectType() {
return UserService.class;
}
// 可选:指定是否单例(默认 true)
@Override
public boolean isSingleton() {
return true;
}
}
// 2. Spring 配置
<bean id="userService" class="com.example.UserServiceFactoryBean"/>
// 3. 测试(Spring 会自动调用 getObject() 获取实例)
5. 注解驱动实例化(主流)
基于注解的方式是现代 Spring 开发的主流,替代 XML 配置,核心注解包括:
@Component:通用注解(标注普通 Bean);@Service:标注业务层 Bean;@Controller:标注控制层 Bean;@Repository:标注数据访问层 Bean;@Configuration + @Bean:标注配置类,通过方法返回 Bean 实例。
代码示例(@Component 方式):
// 1. 标注注解
@Service // 等同于在 XML 中定义 Bean
public class UserService {
public void sayHello() {
System.out.println("Hello, Annotation!");
}
}
// 2. 开启注解扫描(XML 或配置类)
<!-- XML 方式开启扫描 -->
<context:component-scan base-package="com.example"/>
// 或配置类方式(推荐)
@Configuration
@ComponentScan("com.example") // 扫描指定包下的注解 Bean
public class SpringConfig {}
// 3. 测试
public class Test {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = context.getBean(UserService.class);
userService.sayHello(); // 输出:Hello, Annotation!
}
}
代码示例(@Configuration + @Bean 方式):
// 1. 配置类中定义 Bean
@Configuration
public class SpringConfig {
// 方法返回值即为 Bean 实例,方法名默认是 Bean 的 id
@Bean
public UserService userService() {
return new UserService();
}
}
// 2. 测试(直接获取 Bean)
6. 通过 BeanDefinition 手动实例化(底层)
这是最底层的方式,直接操作 Spring 的 BeanDefinition(Bean 的定义元数据),通过编程式方式向容器注册 Bean,适用于框架开发或动态创建 Bean。
适用场景:自定义 Spring 扩展、动态生成 Bean。
代码示例:
public class Test {
public static void main(String[] args) {
// 1. 创建 BeanFactory 容器
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 2. 构建 BeanDefinition(定义 Bean 的元数据)
BeanDefinition beanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(UserService.class)
.getBeanDefinition();
// 3. 注册 BeanDefinition 到容器
beanFactory.registerBeanDefinition("userService", beanDefinition);
// 4. 获取 Bean 实例
UserService userService = beanFactory.getBean("userService", UserService.class);
userService.sayHello();
}
}
二、不同方式的使用场景总结
| 实例化方式 | 核心特点 | 适用场景 |
|---|---|---|
| 构造器实例化 | 简单、默认支持 | 普通业务 Bean(无复杂创建逻辑) |
| 静态工厂方法 | 统一控制实例创建 | 第三方类库、单例对象 |
| 实例工厂方法 | 工厂可维护状态、依赖其他 Bean | 需多实例工厂、工厂依赖注入 |
| FactoryBean 接口 | 自定义创建逻辑、控制初始化 | 复杂对象(数据源、SqlSessionFactory) |
| 注解驱动实例化 | 简洁、主流 | 现代 Spring 项目(Spring Boot) |
| BeanDefinition 手动 | 底层、灵活 | 框架开发、动态创建 Bean |
总结
- 日常开发优先用注解:
@Service/@Controller/@Bean是 Spring Boot 主流,简洁高效; - 基础方式是构造器:Spring 默认通过无参构造器实例化 Bean,是所有方式的基础;
- 复杂场景用工厂:
FactoryBean适合复杂对象创建,静态 / 实例工厂适合统一控制实例逻辑。
核心记住:Spring 实例化 Bean 的本质是 IoC 容器根据 Bean 的定义(XML / 注解 / BeanDefinition),调用对应的创建逻辑(构造器 / 工厂方法)生成实例,最终将实例存入容器供使用。
以上就是Spring实例化bean的6种常见方式详解的详细内容,更多关于Spring实例化bean的资料请关注脚本之家其它相关文章!
