目录
一、spring容器实例化bean的几种方式。
二、spring容器使用实例工厂方式实现bean实例化。
(1)实例工厂?
(2)实例工厂与静态工厂方式的联系与区别。
1、联系。
2、静态工厂。
3、实例工厂。
(3)使用实例工厂方式实现bean实例化一般步骤。
1、将实例工厂交给spring容器管理。(工厂被spring管理)
2、实例工厂Bean创建其他被spring管理的Bean。
<1>属性factory_bean。
<2>属性factory_method。
(4)总结spring容器实例化bean使用静态工厂与实例工厂大致区别。
-
本篇博客接着上篇《spring容器使用静态工厂实例化bean》继续学习。
一、spring容器实例化bean的几种方式。
- 使用构造方法实例化bean。spring学习(spring-bean实例化(无参构造与有参构造方法实现)详解)-CSDN博客
- 使用静态工厂方式实例化bean。spring学习(spring-bean实例化(静态工厂))-CSDN博客
- 其它实例化bean的方式。
二、spring容器使用实例工厂方式实现bean实例化。
- 实例工厂涉及spring配置文件中标签<bean>的2个属性:factory_bean、factory_method。
(1)实例工厂?
- 在spring中,使用实例工厂(Instance Factory)来创建bean实例是一种比较灵活的方式。
- 这种方式涉及到一个被spring容器管理的实例工厂Bean。可以用该实例工厂Bean的实例方法去创建其他bean的实例。
(2)实例工厂与静态工厂方式的联系与区别。
1、联系。
无论是静态工厂还是实例工厂,它们的主要目的都是提供一种机制,使得Spring容器可以通过非构造函数的方式创建bean实例。
在spring配置文件中,都可以使用<bean>标签的factory-method属性来指定创建bean的方法。
两种方式都提供了比直接使用构造函数创建bean更高的灵活性。
两种方式都允许在创建bean实例时执行额外的逻辑。
2、静态工厂。
- 静态方法不能注入其他bean,因为它们是静态的,不属于类的任何特定实例。
- 静态工厂方法创建的bean,spring无法管理其生命周期。因为它们是通过静态方法创建的。
- 适用于不需要依赖注入其他bean,且创建逻辑较为简单的场景。
3、实例工厂。
- 实例方法可以注入其他bean,因为它们是类的实例的一部分,可以访问spring容器中管理的其他bean。
- 实例工厂方法创建的bean,spring可以管理其生命周期。因为实例工厂bean本身是spring容器管理的bean。
- 适用于需要依赖注入其他bean,或者创建逻辑较为复杂,需要访问spring容器中其他bean的场景。
(3)使用实例工厂方式实现bean实例化一般步骤。
- 本篇博客的demo(测试项目)主要分为工厂包(factory)、实体包(entity)、测试包(test)。
- 工厂类(BallFactory)、实体类(Basketball)、测试类(MainApp)。
- 项目的pom.xml文件导入spring-context依赖。
- 最终目的:利用"球"实例工厂的实例方法生成"篮球"实体类(Basketball)的bean!
1、将实例工厂交给spring容器管理。(工厂被spring管理)
- 在spring配置文件中配置"球"(BallFactory)实例工厂。这样就完成第一步:将工厂Bean交给spring容器进行管理。
<?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="ballFactory" class="com.fs.factory.BallFactory" ></bean> </beans>
2、实例工厂Bean创建其他被spring管理的Bean。
<1>属性factory_bean。
- 在spring配置文件中配置"篮球"实例类(Basketball)的bean。
- 通过属性"factory_bean"指定生产"篮球"(Basketball)bean的"球"(BallFactory)实例工厂<bean>绑定的id。则该属性值就是对应(BallFactory)实例工厂对应<bean>标签的id。
- 含义:指定某个实例工厂(通过id)为当前<bean>标签所属类进行实例化服务。
<2>属性factory_method。
- 通过属性"factory_method"指定(BallFactory)实例工厂的实例方法名!
- 含义:指定实例工厂的某个方法(通过方法名)为当前<bean>标签所属类实例化bean。
- 完善"球"实例工厂类(BallFactory)的代码。
package com.fs.factory;import com.fs.entity.Basketball;//生产球(ball)的工厂类 public class BallFactory {public Basketball createBean() {//返回basketball(篮球类)的实例return new Basketball();} }
- 完善spring配置文件。配置实例工厂的bean与实体类的bean。
<?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="ballFactory" class="com.fs.factory.BallFactory" ></bean><!--配置生产"篮球"(Basketball)bean的实例工厂与实例方法--><bean id="basketball" class="com.fs.entity.Basketball" factory-bean="ballFactory" factory-method="createBean"></bean> </beans>
- 完善"篮球"实体类(Basketball)。
package com.fs.entity; //篮球类 public class Basketball { }
- 完善测试类(MainApp)。
package com.fs.test;import org.springframework.context.support.ClassPathXmlApplicationContext;//测试类 public class MainApp {public static void main(String[] args) {//使用IoC容器(ApplicationContext)获取spring容器管理的bean对象//1.创建容器对象。实例化时参数指定对应的配置文件ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springBean.xml");//2.通过<bean>标签的唯一标识id获取对应在spring容器已经配置的bean对象(内部就是通过实例工厂的实例方法获得bean)Object obj = context.getBean("basketball");System.out.println(obj);} }
- 测试结果。
- 注意:图片中代码的注释没来得及更改,具体正确注释看上面代码。
(4)总结spring容器实例化bean使用静态工厂与实例工厂大致区别。
- 1、使用实例工厂方式时:<bean>标签中属性"factory_bean"的值不能设定为自己的id(不能指定自己是实例工厂,然后在自己的类中创建实例方法实例化自己的bean)。
- 2、使用实例工厂方式时:<bean>标签中属性"factory_bean"的值为生产bean的实例工厂id。<bean>标签中属性"factory_method"的值为实例工厂类的实例方法名。
- 3、使用静态工厂方式时:可以在静态方法返回自己的bean,也可以返回别人的bean。(类似于"借鸡生蛋"或"偷梁换柱"的效果)