一、spring bean的依赖关系
首先需要清楚的是spring bean的创建顺序,默认情况下是根据bean.xml中的配置顺序来创建的 如果按照下面这样的配置,如果你在A、B、C三个类的构造器中都添加了打印语句,可以很明显看出 他会先执行A的构造方法,再执行B的构造方法,最后打印C的构造方法。
<bean id = "a" class="com.xxx.spring.demo.entity.A"/>
<bean id = "b" class="com.xxx.spring.demo.entity.B"/>
<bean id = "c" class="com.xxx.spring.demo.entity.C"/>
通过depends-on属性可以手动指定bean创建时的依赖关系 如下面的xml配置所示,创建C的时候必须要先创建A
<bean id = "c" class="com.xxx.spring.demo.entity.C" depends-on="a"/>
二、spring bean的作用域
spring的bean默认有四种作用域,分别是prototype、singleton、session、request 可以通过scope属性来指定bean的作用域
- prototype 该bean可以有多个实例
- singleton 该bean只能有一个实例
- request 该bean在一次请求内唯一,仅对web工程有用
- session 该bean在一次会话内有效,仅对web工程有效
<bean id = "student3" class="com.xxx.spring.demo.entity.Student" parent="student2" scope="singleton"/>
三、通过工厂方法创建bean
这种模式适合创建批量的复杂对象。通过工厂方法创建bean主要有两种实现
- 静态工厂 工厂类不需要要实例化
- 实例工厂 工厂类需要被实例化
(一)通过静态工厂来创建bean
通过静态工厂创建bean,示例如下,创建了一个Airplane实体类,以及一个StasticsAirPlaneFactory的静态工厂类
- Airplane类
public class AirPlane { private String name; private String engine; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEngine() { return engine; } public void setEngine(String engine) { this.engine = engine; } }
- StasticsAirPlaneFactory类
public class StasticsAirPlaneFactory { public static AirPlane createAirplane(String engine, String name){ AirPlane airPlane = new AirPlane(); airPlane.setEngine(engine); airPlane.setName(name); return airPlane; } }
- xml配置
<!--通过静态工厂来创建bean--> <bean id="airPlane1" class="com.haici.spring.demo.factory.StasticsAirPlaneFactory" factory-method="createAirplane"> <constructor-arg name="name" value="歼11"/> <constructor-arg name="engine" value="国产引擎"/> </bean>
(二)通过实例工厂来创建bean
- Airplane类
实体类同上面静态工厂的的Airplane - InstanceAirplaneFactory类
public class InstanceAirplaneFactory { public AirPlane createAirplane(String engine, String name){ AirPlane airPlane = new AirPlane(); airPlane.setEngine(engine); airPlane.setName(name); return airPlane; } }
- xml配置
<!--通过实例工厂来创建bean 首先创建实例工厂bean--> <bean id="instanceAirplaneFactory" class="com.haici.spring.demo.factory.InstanceAirplaneFactory"/> <bean id="airPlane2" class="com.haici.spring.demo.factory.StasticsAirPlaneFactory" factory-bean="instanceAirplaneFactory" factory-method="createAirplane"> <constructor-arg name="name" value="歼11"/> <constructor-arg name="engine" value="国产引擎"/> </bean>
四、通过实现FactoryBean接口的方式来创建bean
这种方式创建的bean无论bean是单例还是多实例,都是在调用getObject方法的时候才会去创建对象,类似于懒加载
- MyFactoryBean类
public class MyFactoryBean implements FactoryBean<AirPlane> { /** * 返回创建的对象 * @return * @throws Exception */ public AirPlane getObject() throws Exception { System.out.println("通过factorybean的方式来创建airplane对象"); AirPlane airPlane = new AirPlane(); airPlane.setName("歼20"); airPlane.setEngine("国产引擎"); return airPlane; } /** * 返回创建对象的类型 Spring会调用这个方法来确认创建的对象时什么类型 * @return */ public Class<?> getObjectType() { return AirPlane.class; } /** * 是否是单例 * @return */ public boolean isSingleton() { return true; } }
- xml配置
<!--通过实现factoryBean接口的方式来创建bean--> <bean id="myfactry" class="com.haici.spring.demo.factory.MyFactoryBean"/>
- App类
启动类获取对应的bean 如下面的代码所示 id是MyFactoryBean的id但是获取出来的是getObject() 方法返回过来的airplane对象AirPlane airPlane4 = context.getBean("myfactry", AirPlane.class);