实例化bean的三种方式

本文介绍了Spring框架中Bean的三种创建方式:使用构造器创建、通过静态工厂方法创建及通过实例工厂方法创建。每种方式均有详细的步骤说明及应用场景分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


通常情况下,class属性通常是必须的(除了实例工厂方法创建bean和子bean的定义).大多数情况下,BeanFactory直接调用构造函数来"new"一个bean,class属性确定bean实例的实现类.但这并不是创建bean的唯一方法.创建bean有如下三种方法:
 一、调用构造器"new"一个bean实例.
 二、BeanFactory调用某个类的静态工厂方法创建bean.
 三、BeanFactory调用实例工厂方法创建bean

 

<1>调用构造器"new"一个bean实例.的执行过程:
程序创建BeanFactory实例. (org.springframework.beans.factory.support.DefaultListableBeanFactory)
调用Chinese类的默认构造器创建默认实例.
根据配置文件注入依赖关系,先实例化依赖bean,然后将依赖bean注入。
返回一个完整的JavaBean实例。
配置文件:<bean id="students" class="ioc.beans.StudentsBean" />

 

<2>BeanFactory调用某个类的静态工厂方法创建bean.
  使用静态工厂方法创建bean实例时,class属性确定静态工厂类,而不是该bean的类。spring需要知道哪个静态工厂方法创建的bean实例,使用factory-method属性来确定方法名。Spring调用工厂方法(也包含一组参数),并返回一个有效的对象。之后,bean实例的使用与采用其他方法创建的完全一样。如果静态工厂方法需要参数,使用<constructor-arg>元素传入。
class元素不再是bean的实现类,而是静态工厂类;
必需有factory-method属性确定产生实例的静态工厂方法;
静态工厂方法需要参数,则使用<constructor -arg>元素确定静态工厂方法.
配置文件:<bean id="students2" class="ioc.instanceBean_3way.StaticFactory_Sec" factory-method="createStudent"/>

 

<3>调用实例工厂方法创建bean
通过实例工厂方法创建bean时,bean元素不能含有class属性.因为BeanFactory不再直接实例化该bean,BeanFactory仅仅执行工厂的方法,工厂的方法返回bean实例.采用实例工厂方法创建bean应指定如下两个属性.
工厂bean的id,该id属性应该对应spring容器中的一个bean
工厂方法名,该方法可产生bean实例.
与静态工厂方法相似,如果需要在调用工厂方法时传入参数,使用<constructor-arg>元素确定参数值
配置文件:
 <bean id="factory" class="ioc.instanceBean_3way.InstanceFactory_Thr"/>
 <bean id="students3" factory-bean="factory" factory-method="createStudent"/>


总结:
一、使用类构造器实例化:通过bean的缺省构造函数(org.springframework.beans.factory.support.DefaultListableBeanFactory)默认创建,当各个bean的业务逻辑相互比较独立的时候或者和外界关联较少的时候可以使用。
二、静态工厂方法实例化:利用静态factory方法创建,可以统一管理各个bean的创建,如各个bean在创建之前需要相同的初始化处理,则可用这个factory方法险进行统一的处理等等。

三、实例工厂方法实例化:利用实例化factory方法创建,即将factory方法也作为了业务bean来控制,觉得1可用于集成其他框架的bean创建管理方法,2能够使bean和factory的角色互换。

 

PS:感谢 肖麦  http://www.blogjava.net/merek/articles/109333.html

<think>嗯,用户问的是实例化Bean有几种方式。首先,我需要确定用户是在什么上下文中提问的。通常,Bean这个概念在Spring框架中经常被提到,所以可能用户是在学习Spring或者Java EE相关的知识。不过,也有可能用户指的是其他框架中的Bean,但考虑到之前的对话中提到了Java的ReentrantLock,可能还是Spring的可能性更大。 接下来,我需要回忆一下Spring实例化Bean的几种方式。一般来说,常见的包括构造函数实例化、静态工厂方法、实例工厂方法,还有通过FactoryBean接口的方式。另外,可能还有使用@Bean注解的方式,以及通过Java配置类或者XML配置的不同方法。不过,用户问的是“几种方式”,可能需要归类总结。 然后,我需要考虑用户可能的背景。如果用户是初学者,可能需要用更简单易懂的语言来解释,避免太专业的术语。但之前的回答中用户已经接触过公平锁和非公平锁这样的概念,可能有一定的技术基础,所以可以适当深入一些。 另外,用户可能想知道不同方式的优缺点,或者适用场景,所以在介绍每种方式的时候,可能需要简要说明为什么选择这种方式,或者什么时候用比较合适。例如,构造函数实例化是最直接的,而工厂方法可能在需要复杂初始化的时候使用。 还需要注意是否有其他实例化方式,比如使用注解如@Component、@Service等,这些是否算作不同的实例化方式?其实这些是基于组件扫描的,底层还是通过反射调用默认构造函数,所以可能可以归类到构造函数实例化里面。 另外,XML配置和Java配置的区别,虽然配置方式不同,但实例化方式可能还是那几种。例如,XML中的<bean>标签使用class属性指定类,这就是构造函数实例化;而factory-method指定静态工厂方法,或者factory-bean加上factory-method指定实例工厂方法。 可能还需要提到一些特殊的情况,比如使用FactoryBean接口,这种时候获取的Bean实际上是FactoryBean的getObject()方法返回的对象,而不是FactoryBean本身。这点需要解释清楚,避免混淆。 然后,是否需要举例说明?比如代码示例,或者配置示例,这样用户更容易理解。不过之前的回答中已经有Java代码示例,可能用户比较习惯看代码,所以可以考虑加入简单的例子。 最后,总结一下,确保覆盖所有主要的实例化方式,并且结构清晰,让用户能够一目了然地看到每种方式的区别和适用情况。同时,注意不要遗漏重要的点,比如通过Java配置类中的@Bean方法,其实也是一种工厂方法的方式,可能属于静态或实例工厂方法的一种变种。 可能的误区:用户可能认为使用注解如@Autowired也是实例化方式,但实际上那属于依赖注入的范畴,而实例化指的是创建Bean的过程。需要明确区分实例化和注入的不同阶段。 另外,是否需要提到原型作用域和单例作用域对实例化的影响?不过用户的问题是关于实例化方式,而不是作用域,所以可能不需要展开,除非有直接关联。 总之,需要整理出几种主要的实例化方式,每种方式的定义、实现方法、适用场景,以及可能的代码或配置示例,帮助用户全面理解。在</think> Spring 框架中,实例化 Bean 的常见方式有以下几种,每种方式适用于不同的场景: --- ### **1. 默认构造函数(无参构造)** #### **定义** 通过类的**无参构造函数**创建 Bean 实例,是 Spring 默认且最常用的方式。 #### **实现** - **XML 配置**: ```xml <bean id="userService" class="com.example.UserService" /> ``` - **注解**: 使用 `@Component`、`@Service`、`@Controller` 等注解标记类,配合组件扫描(`@ComponentScan`)。 ```java @Service public class UserService { /* ... */ } ``` #### **特点** - 简单直接,无需额外配置。 - 要求类必须有无参构造函数(否则抛异常)。 --- ### **2. 静态工厂方法(Static Factory Method)** #### **定义** 通过类的**静态方法**返回 Bean 实例,常用于整合遗留代码或复杂初始化逻辑。 #### **实现** - **XML 配置**: ```xml <bean id="client" class="com.example.ClientFactory" factory-method="createClient" /> ``` - **Java 代码示例**: ```java public class ClientFactory { public static Client createClient() { return new Client(); // 可包含复杂初始化逻辑 } } ``` #### **特点** - 工厂方法必须是静态的。 - 适用于创建过程需要条件判断或资源预加载的场景。 --- ### **3. 实例工厂方法(Instance Factory Method)** #### **定义** 通过**某个 Bean 的实例方法**创建另一个 Bean,适合工厂类本身需要依赖注入的场景。 #### **实现** - **XML 配置**: ```xml <!-- 先定义工厂 Bean --> <bean id="clientFactory" class="com.example.ClientFactory" /> <!-- 通过工厂 Bean 的方法创建目标 Bean --> <bean id="client" factory-bean="clientFactory" factory-method="createClient" /> ``` - **Java 代码示例**: ```java public class ClientFactory { public Client createClient() { return new Client(); // 实例方法 } } ``` #### **特点** - 工厂类本身是一个 Spring Bean(可被其他 Bean 依赖)。 - 适合工厂需要动态配置的场景。 --- ### **4. 实现 `FactoryBean` 接口** #### **定义** 通过实现 `FactoryBean` 接口自定义 Bean 的创建逻辑,适用于创建复杂对象(如 MyBatis 的 `SqlSessionFactoryBean`)。 #### **实现** ```java public class MyFactoryBean implements FactoryBean<MyObject> { @Override public MyObject getObject() { return new MyObject(); // 实际返回的 Bean } @Override public Class<?> getObjectType() { return MyObject.class; } @Override public boolean isSingleton() { return true; // 单例模式 } } ``` #### **特点** - 通过 `getObject()` 返回目标 Bean。 - 需注册 `FactoryBean` 到容器(XML 或 `@Bean`)。 --- ### **5. 基于 Java 配置类(`@Bean` 方法)** #### **定义** 在配置类中使用 `@Bean` 注解的方法返回实例,等同于工厂方法,但更灵活。 #### **实现** ```java @Configuration public class AppConfig { @Bean public DataSource dataSource() { // 可包含初始化逻辑(如连接池配置) return new HikariDataSource(); } } ``` #### **特点** - 结合 `@Configuration` 使用,方法可调用其他 `@Bean` 方法。 - 适合需要编程式初始化的场景。 --- ### **6. 构造器注入参数(带参构造函数)** #### **定义** 通过构造函数传入参数实例化 Bean,常用于依赖注入。 #### **实现** - **XML 配置**: ```xml <bean id="userService" class="com.example.UserService"> <constructor-arg ref="userRepository" /> </bean> ``` - **注解**: ```java @Service public class UserService { private final UserRepository userRepository; @Autowired // Spring 4.3+ 可省略 public UserService(UserRepository userRepository) { this.userRepository = userRepository; } } ``` #### **特点** - 显式声明依赖关系,适合强类型安全场景。 --- ### **对比与选择建议** | **方式** | **适用场景** | **优点** | **缺点** | |---| | **默认构造函数** | 简单 Bean,无复杂初始化逻辑 | 配置简单,直观 | 依赖无参构造 | | **静态工厂方法** | 整合遗留代码或复杂对象创建 | 隐藏创建细节,复用代码 | 工厂类需静态方法 | | **实例工厂方法** | 工厂类本身需要依赖注入 | 灵活,支持动态配置 | 需先实例化工厂类 | | **`FactoryBean` 接口** | 创建第三方库复杂对象(如数据库连接) | 完全控制 Bean 生命周期 | 实现稍复杂 | | **`@Bean` 方法** | 需要编程式初始化或条件创建 | 灵活性高,代码即配置 | 需手动管理依赖 | | **构造器注入参数** | 显式依赖注入 | 强类型安全,避免循环依赖 | 参数较多时配置繁琐 | --- ### **总结** Spring 提供了多种实例化 Bean方式,核心目的是**平衡灵活性与简洁性**。 - **默认构造器**和**构造器注入**适合常规场景。 - **工厂方法**和 `FactoryBean` 用于复杂初始化逻辑。 - **Java 配置类**(`@Bean`)是现代 Spring 应用的推荐方式,结合注解可大幅简化配置。 根据业务需求选择合适的方式,避免过度设计!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值