spring系列:三、Bean的实例化和获取
程序员文章站
2022-03-12 17:11:34
...
Bean的实例化和获取
ApplicationContext与BeanFactory的关系
- BeanFactory就是一个ioc容器,它采用的是延迟加载的策略,也就是只有在getBean的时候才会实例化bean
- ApplicationContext是BeanFactory的扩展接口,它采用的是立即加载的策略,也就是在配置文件加载的时候就会实例化bean。它提供了不同应用层的context的实现,例如在web开发中可以使用的WebApplicationContext
- FileSystemXmlAppliCationContext,ApplicationContext的实现类,根据文件路径获取获取配置文件
- ClassPathXmlApplicationContext,ApplicationContext的实现类,根据文件名称在classpath路径下查找
Bean的实例化
-
方式一:无参数构造
<!-- 此种方式创建的bean必须提供无参构造 --> <bean name="bean1" class="cn.ade.domain.Bean1"/>
-
方式二:静态工厂方法
public class Bean3Factory { /** * 使用静态方法获取对象 * * @return */ public static Bean3 createBean3() { return new Bean3(); } }
<!-- 使用静态工厂的方法实例化对象 --> <bean name="bean3" class="cn.ade.utils.Bean3Factory" factory-method="createBean3"/>
-
方式三:实例工厂方式
public class Bean4Factory { /** * 使用非静态方法获取对象 * * @return */ public Bean4 getBean4() { return new Bean4(); } }
<!-- 使用实例工厂的方法实例化对象 --> <bean name="bean4Factory" class="cn.ade.utils.Bean4Factory"/> <bean name="bean4" factory-bean="bean4Factory" factory-method="getBean4"/>
bean的作用域
在创建bean的时候,有一个scope属性,可取的值:
- singleton,默认,单例模式,ioc容器中只有一个bean的实例
- prototype,多例模式,每次从ioc容器中获取bean的时候,都会实例化一个新的bean
- request,用在web开发中,将bean存储在request域中。简单来讲,request可以看做prototype的一种特例,除了场景更加具体之外,语意上差不多。
- session,用在web开发中,将bean存储在session域中。
- global session,只有应用在基于porlet的web应用程序中才有意义,它映射到porlet的global范围的session,如果普通的servlet的web 应用中使用了这个scope,容器会把它作为普通的session的scope对待。
bean的生命周期
- 第一步,instantiate bean,对象实例化 - 构造函数
- 第二步,populate properties,封装属性 - set方法
- 第三步,如果实现了BeanNameAware接口,执行方法setBeanName
- 第四步,如果实现了 BeanFactoryAwar 或 ApplicationContextAwar 接口,在这里设置工厂 setBeanFactory 或上下文对象 setApplicationContext
- 第五步,如果存在类实现 BeanPostProcess(后处理 Bean),执行 postProcessBeforeInitialization
- 第六步,如果实现了InitializingBean接口,执行 afterPropertiesSet - 增强
- 第七步,调用自定义的 init-method 方法
- 第八步,如果存在类实现 BeanPostProcessor(处理 Bean),执行 postProcessAfterInitialization - 增强
- 第九步,执行业务方法
- 第十步,如果实现了 DisposableBean 执行 destroy
- 第十一步,调用自定义的 destroy-method,destroy-method 只对 scope=singleTon 有效果
public class Bean5 implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
/**
* 成员变量
*/
private String info;
/**
* 空参构造
* 在加载配置文件的时候,或者getBean的时候
*/
public Bean5() {
System.out.println("第一步:Bean5的实例化");
}
/**
* 对成员变量info进行赋值
*
* @param info
*/
public void setInfo(String info) {
System.out.println("第二步:Bean5的属性注入");
this.info = info;
}
/**
* 如果 Bean 实现 BeanNameAware 执行 setBeanName
*
* @param s
*/
@Override
public void setBeanName(String s) {
System.out.println("第三步:获取bean的id或name值:"+s);
}
/**
* 如果 Bean 实现 BeanFactoryAwar 或 ApplicationContextAwar 设置工厂 setBeanFactory 或上下文对象 setApplicationContext
*
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("第四步:得到ApplicationContext对象:"+applicationContext);
}
/**
* 如果 Bean 实现 InitializingBean 执行 afterPropertiesSet
*
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("第六步:属性注入完成后···");
}
/**
* 调用自定义的 init-method 方法
*/
public void MyInitMethod() {
System.out.println("第七步:自定义的初始化方法");
}
/**
* 测试方法
*/
public void show() {
System.out.println("第九步:执行业务操作");
}
/**
* 如果 Bean 实现 DisposableBean 执行 destroy
*
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("第十步:销毁");
}
/**
* 调用自定义的 destroy-method,destroy-method 只对 scope=singleTon 有效果
*/
public void MyDestroyMethod() {
System.out.println("第十一步:自定义的销毁方法");
}
}
public class MyBeanPostProcess implements BeanPostProcessor {
/**
* 如果存在类实现 BeanPostProcess(后处理 Bean),执行 postProcessBeforeInitialization
*
* @param o
* @param s
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("第五步:存在类实现 BeanPostProcess(后处理 Bean),执行 postProcessBeforeInitialization");
return o;
}
/**
* 如果存在类实现 BeanPostProcessor(处理 Bean),执行 postProcessAfterInitialization
*
* @param o
* @param s
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("第八步:存在类实现 BeanPostProcessor(处理 Bean),执行 postProcessAfterInitialization");
return o;
}
}
<!-- Bean的声明周期 -->
<bean name="bean5" class="cn.ade.domain.Bean5" init-method="MyInitMethod" destroy-method="MyDestroyMethod" scope="singleton">
<property name="info" value="Bean5"/>
</bean>
<bean class="cn.ade.utils.MyBeanPostProcess"/>
上一篇: vue快速入门
下一篇: UE4蓝图转C++:节点转换(持续更新)
推荐阅读
-
spring源码分析系列5:ApplicationContext的初始化与Bean生命周期
-
Spring启动后获取所有拥有特定注解的Bean实例代码
-
02Spring基于xml的IOC配置--实例化Bean的三种方式
-
Python的地形三维可视化Matplotlib和gdal使用实例
-
Spring5 - Bean的初始化和销毁的4种方式
-
Spring Bean的实例化之属性注入源码剖析过程
-
Spring中bean的初始化和销毁几种实现方式详解
-
关于Spring Bean实例过程中使用反射和递归处理的Bean属性填充问题
-
Spring实例化Bean的五种方式
-
聊聊spring之bean对象的实例化过程