温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Spring-IOC的高级特性有哪些

发布时间:2021-10-13 09:46:34 来源:亿速云 阅读:131 作者:iii 栏目:编程语言

本篇内容介绍了“Spring-IOC的高级特性有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

lazy-Init 延迟加载 

Bean的延迟加载(延迟创建)

ApplicationContext 容器的默认行为是在启动服务器时将所有 singleton bean 提前进行实例化。提前实例化意味着作为初始化过程的⼀部分,ApplicationContext 实例会创建并配置所有的singleton bean。

比如:

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

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

 <bean id="testBean" calss="cn.bxc.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)开启延迟加载⼀定程度提高容器启动和运转性能
(2)对于不常使用的 Bean 设置延迟加载,这样偶尔使用的时候再加载,不必要从⼀开始该 Bean 就占用资源

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.bxc.edu.pojo;


 /**
     * @author bixc
     */
 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.bxc.edu.factory;


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


 /**
     * @author bixc
     */
 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.bxc.edu.factory.CompanyFactoryBean">
         <property name="companyInfo" value="阿里,中关村,500"/>
 </bean>


测试,获取FactoryBean产生的对象

 Object companyBean = applicationContext.getBean("companyBean");
 System.out.println("bean:" + companyBean);


 // 结果如下
 bean:Company{name='阿里', address='中关村', scale=500}

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

Object companyBean = applicationContext.getBean("&companyBean");
 System.out.println("bean:" + companyBean);


 // 结果如下
 bean:com.bxc.edu.factory.CompanyFactoryBean@53f6fd09

后置处理器

Spring提供了两种后处理bean的扩展接口,分别为 BeanPostProcessor 和BeanFactoryPostProcessor,两者在使用上是有所区别的。

工厂初始化(BeanFactory)—> Bean对象

在BeanFactory初始化之后可以使用BeanFactoryPostProcessor进行后置处理做⼀些事情

在Bean对象实例化(并不是Bean的整个生命周期完成)之后可以使用BeanPostProcessor进行后置处理做⼀些事情

注意:对象不⼀定是springbean,而springbean一定是个对象

BeanPostProcessor

BeanPostProcessor是针对Bean级别的处理,可以针对某个具体的Bean.

Spring-IOC的高级特性有哪些

该接口提供了两个方法,分别在Bean的初始化方法前和初始化方法后执行,具体这个初始化方法指的是什么方法,类似我们在定义bean时,定义了init-method所指定的方法

定义⼀个类实现了BeanPostProcessor,默认是会对整个Spring容器中所有的bean进行处理。如果要对具体的某个bean处理,可以通过方法参数判断,两个类型参数分别为Object和String,第⼀个参

数是每个bean的实例,第⼆个参数是每个bean的name或者id属性的值。所以我们可以通过第⼆个参数,来判断我们将要处理的具体的bean。

注意:处理是发生在Spring容器的实例化和依赖注⼊之后。

BeanFactoryPostProcessor

BeanFactory级别的处理,是针对整个Bean的工厂进行处理,典型应用:PropertyPlaceholderConfigurerSpring-IOC的高级特性有哪些

此接口只提供了⼀个方法,方法参数为ConfigurableListableBeanFactory,该参数类型定义了⼀些方法Spring-IOC的高级特性有哪些

其中有个方法名为getBeanDefinition的方法,我们可以根据此方法,找到我们定义bean 的BeanDefinition对象。然后我们可以对定义的属性进行修改,以下是BeanDefinition中的方法Spring-IOC的高级特性有哪些

方法名字类似我们bean标签的属性,setBeanClassName对应bean标签中的class属性,所以当我们拿到BeanDefinition对象时,我们可以手动修改bean标签中所定义的属性值。

BeanDefinition对象:我们在 XML 中定义的 bean标签,Spring 解析 bean 标签成为⼀个 JavaBean,这个JavaBean 就是 BeanDefinition

注意:调用 BeanFactoryPostProcessor 方法时,这时候bean还没有实例化,此时 bean 刚被解析成BeanDefinition对象

“Spring-IOC的高级特性有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI