Spring IOC⾼级特性

2.1 lazy-Init 延迟加载
Bean的延迟加载(延迟创建)
ApplicationContext 容器的默认⾏为是在启动服务器时将所有 singleton bean 提前进⾏实例化。提前
实例化意味着作为初始化过程的⼀部分,ApplicationContext 实例会创建并配置所有的singleton
bean。
⽐如:

<bean id="testBean" class="cn.lagou.LazyBean" />
该bean默认的设置为: <bean id="testBean" calss="cn.lwl.LazyBean" lazy-init="false" />

lazy-init=“false”,⽴即加载,表示在spring启动时,⽴刻进⾏实例化。
如果不想让⼀个singleton bean 在 ApplicationContext实现初始化时被提前实例化,那么可以将bean
设置为延迟实例化。

<bean id="testBean" calss="cn.lagou.LazyBean" lazy-init="true" />

设置 lazy-init 为 true 的 bean 将不会在 ApplicationContext 启动时提前被实例化,⽽是第⼀次向容器
通过 getBean 索取 bean 时实例化的。
如果⼀个设置了⽴即加载的 bean1,引⽤了⼀个延迟加载的 bean2 ,那么 bean1 在容器启动时被实例
化,⽽ bean2 由于被 bean1 引⽤,所以也被实例化,这种情况也符合延时加载的 bean 在第⼀次调⽤
时才被实例化的规则。
也可以在容器层次中通过在 元素上使⽤ “default-lazy-init” 属性来控制延时初始化。如下⾯配置:

<beans default-lazy-init="true">
 <!-- no beans will be eagerly pre-instantiated... -->
</beans>

如果⼀个 bean 的 scope 属性为 scope=“pototype” 时,即使设置了 lazy-init=“false”,容器启动时也不
会实例化bean,⽽是调⽤ getBean ⽅法实例化的。
应⽤场景
(1)开启延迟加载⼀定程度提⾼容器启动和运转性能

该bean默认的设置为:

(2)对于不常使⽤的 Bean 设置延迟加载,这样偶尔使⽤的时候再加载,不必要从⼀开始该 Bean 就占 ⽤资源

2.2 FactoryBean 和 BeanFactory

BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚,
具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext;此处我们重点分析FactoryBean
Spring中Bean有两种,⼀种是普通Bean,⼀种是⼯⼚Bean(FactoryBean),FactoryBean可以⽣成
某⼀个类型的Bean实例(返回给我们),也就是说我们可以借助于它⾃定义Bean的创建过程。
Bean创建的三种⽅式中的静态⽅法和实例化⽅法和FactoryBean作⽤类似,FactoryBean使⽤较多,尤
其在Spring框架⼀些组件中会使⽤,还有其他框架和Spring框架整合时使⽤

// 可以让我们⾃定义Bean的创建过程(完成复杂Bean的定义)
public interface FactoryBean<T> {
 @Nullable
 // 返回FactoryBean创建的Bean实例,如果isSingleton返回true,则该实例会放到Spring容器
的单例对象缓存池中Map
 T getObject() throws Exception;
 @Nullable
 // 返回FactoryBean创建的Bean类型
 Class<?> getObjectType();
 // 返回作⽤域是否单例
 default boolean isSingleton() {
 return true;
 } }

Company类

package com.lwl.edu.pojo;

public class Company {
 private String name;
 private String address;
 private int scale;
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public String getAddress() {
 return address;
 }
 public void setAddress(String address) {
 this.address = address;
 }
 public int getScale() {
 return scale;
 }
 public void setScale(int scale) {
 this.scale = scale;
 }
 @Override
 public String toString() {
 return "Company{" +
 "name='" + name + '\'' +
 ", address='" + address + '\'' +
 ", scale=" + scale +
 '}';
 }
}

CompanyFactoryBean类

package com.lwl.edu.factory;
import com.lwl.edu.pojo.Company;
import org.springframework.beans.factory.FactoryBean;

public class CompanyFactoryBean implements FactoryBean<Company> {
 private String companyInfo; // 公司名称,地址,规模
 public void setCompanyInfo(String companyInfo) {
 this.companyInfo = companyInfo;
 }
 @Override
 public Company getObject() throws Exception {
 // 模拟创建复杂对象Company
 Company company = new Company();
 String[] strings = companyInfo.split(",");
 company.setName(strings[0]);
 company.setAddress(strings[1]);
 company.setScale(Integer.parseInt(strings[2]));
 return company;
 }
 @Override
 public Class<?> getObjectType() {
 return Company.class;
 }
 @Override
 public boolean isSingleton() {
 return true;
 }
}

xml配置

<bean id="companyBean" class="com.lwl.edu.factory.CompanyFactoryBean">
 <property name="companyInfo" value="11111"/>
</bean>

测试,获取FactoryBean产⽣的对象

Object companyBean = applicationContext.getBean("companyBean");
System.out.println("bean:" + companyBean);
// 结果如下
bean:Company{name='IT', address='成都', scale=500}

测试,获取FactoryBean,需要在id之前添加“&

Object companyBean = applicationContext.getBean("&companyBean");
System.out.println("bean:" + companyBean);
// 结果如下
bean:com.lwl.edu.factory.CompanyFactoryBean@53f6fd09

2.3 后置处理器
Spring提供了两种后处理bean的扩展接⼝,分别为 BeanPostProcessor 和
BeanFactoryPostProcessor,两者在使⽤上是有所区别的。
⼯⼚初始化(BeanFactory)—> Bean对象
在BeanFactory初始化之后可以使⽤BeanFactoryPostProcessor进⾏后置处理做⼀些事情
在Bean对象实例化(并不是Bean的整个⽣命周期完成)之后可以使⽤BeanPostProcessor进⾏后置处
理做⼀些事情
注意:对象不⼀定是springbean,⽽springbean⼀定是个对象
SpringBean的⽣命周期
2.3.1 BeanPostProcessor
BeanPostProcessor是针对Bean级别的处理,可以针对某个具体的Bean.

在这里插入图片描述

该接⼝提供了两个⽅法,分别在Bean的初始化⽅法前和初始化⽅法后执⾏,具体这个初始化⽅法指的是
什么⽅法,类似我们在定义bean时,定义了init-method所指定的⽅法
定义⼀个类实现了BeanPostProcessor,默认是会对整个Spring容器中所有的bean进⾏处理。如果要对
具体的某个bean处理,可以通过⽅法参数判断,两个类型参数分别为Object和String,第⼀个参数是每
个bean的实例,第⼆个参数是每个bean的name或者id属性的值。所以我们可以通过第⼆个参数,来判
断我们将要处理的具体的bean。
注意:处理是发⽣在Spring容器的实例化和依赖注⼊之后。
2.3.2 BeanFactoryPostProcessor
BeanFactory级别的处理,是针对整个Bean的⼯⼚进⾏处理,典型应
⽤:PropertyPlaceholderConfigurer

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时小浅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值