目录
- 实例化Bean的方式
- 使用构造函数实例化Bean
- 使用静态工厂的方式实例化Bean
- 使用实例化工厂方式实例化Bean
- 通过实现FactoryBean自定义实例化Bean
实例化Bean的方式
- bean的创建本质上就是创建一个或多个具有外部配置属性的对象,容器在启动的时候会查看命名Bean的配置属性,并使用该Bean Definition封装的配置来创建或获取一个对象。
- Spring提供了利用容器本身通过反射方式调用构造函数直接创建Bean的方式
- 同时也提供了调用静态工厂的方式创建Bean(
需制定要被调用的静态工厂方法的实际类
)
如果是在Bean中定义了一个静态嵌套类, 比如在com.example中有一个叫做Dog的类,在Dog里有一个叫做OurDog的静态嵌套类,在Bean中的定义可以是
class=com.example.Dog$OurDog或者com.example.Dog.OurDog
使用构造函数实例化Bean
- 使用构造函数实例化如果没有任何构造方法的依赖注入,仅仅只需要一个默认为空的构造函数即可,这种方式使得所有普通类都可以被Spring兼容
<bean id="xmlBean" class="com.nobugnolife.bean.impl.XmlBeanImpl"/>
- 有参构造函数会在我之后的文章中进行描述。
使用静态工厂的方式实例化Bean
- 定义一个静态方法创建Bean需要使用class指定包含静态工厂方法的类,并通过factory-method提供需要调用的方法,之后便会通过方法调用对象的构造函数创建并返回。
- 静态工厂类
public class StaticBeanFactory {private static ClientBean clientBean = new ClientBeanImpl();private StaticBeanFactory() {}public static ClientBean createInstance() {return clientBean;}
}
- xml配置
<!-- 使用静态工厂方式实例化bean--><!-- class提供静态工厂的类路径--><!-- factory-method选择创建对应Bean的对象方法 --><bean id="clientBean" class="com.nobugnolife.factory.StaticBeanFactory" factory-method="createInstance"/>
使用实例化工厂方式实例化Bean
- 和静态工厂方法类似,不过实例化工厂需要先从容器中调用工厂Bean本身的方法来创建Bean,我们需要提供factory-bean属性来关联指定创建Bean对象的工厂Bean,并通过factory-method设置调用方法创建对象。
值的注意的是,静态工厂和实例化工厂在bean的属性中都不需要提供指定Bean的class属性,而转为提供对应工厂Bean的class,因为工厂的方法本身就已经和对应的Bean进行了关联
- 需要先创建一个工厂类
public class SampleBeanFactory {private static SampleBean sampleBean = new SampleBeanImpl();public SampleBean createSampleBeanInstance(){return sampleBean;}
}
- 配置xml
<!-- 使用工厂方式实例化bean --><!-- 首先需要将工厂类配置到bean中 --><bean id="sampleBeanFactory" class="com.nobugnolife.factory.SampleBeanFactory"/><!-- 通过factory-bean将工厂bean绑定 --><bean id="sampleBean" factory-bean="sampleBeanFactory" factory-method="createSampleBeanInstance"/>
- 抽象工厂的原理和工厂类似,不过在Spring框架中提供了一个FactoryBean接口,那些本身就是工厂的对象实现 org.springframework.beans.factory.FactoryBean 接口,可以简化实例化工厂的配置。
通过实现FactoryBean自定义实例化Bean
- Spring框架本身提供了FactoryBean接口,允许让本就是工厂的类实现此接口,从而简化XML的表达
- FactoryBean 接口提供三个方法:
- T getObject():返回本工厂创建的对象的一个实例。该实例可能会被共享,这取决于该工厂是返回singleton还是prototype
- boolean isSingleton():如果这个FactoryBean返回的Bean是singleton,则返回true,否则返回false。默认返回true
- Class<?> getObjectType():返回由getObject()方法返回的对象类型,如果事先不知道类型,则返回null
Spring框架大量使用FactoryBean接口,在ApplicantContext相关的实现类中以及其他很多地方都能看到FactoryBean的接口实现类,官方文档的描述中Spring本身就有50多个FactoryBean的接口实现。
- 值得注意的是在调用 ApplicationContext的getBean()方法时,在Bean的id前加(&)会返回 FactoryBean实例本身。
- 创建工厂类并实现FactoryBean接口
public class ImplBeanFactory implements FactoryBean<ImplBean> {@Overridepublic ImplBean getObject() throws Exception {// 这里直接创建实现类对象并返回return new ImplBeanImpl();}@Overridepublic Class<?> getObjectType() {// 返回的是Class类型return ImplBean.class;}@Overridepublic boolean isSingleton() {return FactoryBean.super.isSingleton();}
}
- 配置xml
<!-- 继承FactoryBean接口的工厂会被Spring自动创建到容器中就无需配置工厂bean -->
<!-- 因为是实现的spring规范接口,所以无需提供factory-method,spring会自动调用getObject方法 -->
<bean id="implBean" class="com.nobugnolife.factory.ImplBeanFactory"/>