文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

关于Spring BeanPostProcessor的执行顺序

2024-04-02 19:55

关注

Spring BeanPostProcessor执行顺序

首先 Spring 通过调用构造方法创建 User 对象;

User 对象创建好之后,先不直接进行初始化操作,通过 BeanPostProcessor 对刚创建好的 User 对象进行加工操作,其中 postProcessBeforeInitialization 方法的第一个参数是 User 对象,第二个参数是在配置文件中指定的 id 值;

加工好之后通过 return 将对象返回给 Spring 容器,然后 Spring 容器继续按照流程执行 初始化操作,先是 InitializingBean 的初始化操作;

再是 init-method 的初始化;

然后 Spring 容器再次将对象交给 BeanPostProcessor ,执行 postProcessAfterInitialization 方法。

实际上在实战中,我们很少处理 Spring 的初始化操作,所以没有必要区分 Before 还是 After。只需要实现其中的一个即可,显然选 After 方法更好。

先定义一个实体类 Category:


public class Category {
  private Integer id;
  private String name;
  public Integer getId() {
      return id;
  }
  public void setId(Integer id) {
      this.id = id;
  }
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  @Override
  public String toString() {
      return "Category{" +
              "id=" + id +
              ", name='" + name + '\'' +
              '}';
  }
}

然后注入到 Spring 容器中:


<bean class="edu.lsu.pojo.Category" id="category">
  <property name="id" value="1"/>
  <property name="name" value="迪丽热巴"/>
</bean>

注意此时的名字是迪丽热巴。

此时我们定义一个 BeanPostProcessor,实现他的后置处理器方法:


public class MyBeanPostProcessor implements BeanPostProcessor {
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
  }
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      Category category = (Category) bean;
      category.setName("古力娜扎");
      return category;
  }
}

当我们在此时的时候,输出结果就是古力娜扎;


@Test
public void test7() {
  ApplicationContext ac = new ClassPathXmlApplicationContext("/applicationContext2.xml");
  Category category = ac.getBean("category", Category.class);
  System.out.println("category = " + category);
}

输出:

category = Category{id=1, name='古力娜扎'}

Spring-BeanPostProcessor接口总结

定义

Spring提供了一个BeanPostProcessor接口,这个接口的作用在于对于新构造的实例可以做一些自定义的修改。比如如何构造、属性值的修改、构造器的选择。

如果想改变Spring容器中bean的一些属性或者行为,可以通过自定义类实现BeanPostProcessor接口实现。

以下基本Spring-beans 5.0.6版本说明。

BeanPostProcessor


@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
 return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
 return bean;
}

BeanPostProcessor总结

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor接口继承自BeanPostProcessor接口,定义了3个方法


@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
 return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
 return true;
}
@Nullable
default PropertyValues postProcessPropertyValues(
  PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
 return pvs;
}

InstantiationAwareBeanPostProcessor总结

SmartInstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor接口继承InstantiationAwareBeanPostProcessor接口,定义了3个方法,作用是在于目标对象的实例化过程中需要处理的事情。


@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
 return null;
}
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
  throws BeansException {
 return null;
}
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
 return bean;
}

SmartInstantiationAwareBeanPostProcessor总结

DestructionAwareBeanPostProcessor


void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
default boolean requiresDestruction(Object bean) {
 return true;
}

DestructionAwareBeanPostProcessor总结

postProcessBeforeDestruction方法在目标bean被销毁之前调用,该回调适用于单例bean的使用;

判断目标bean是否需要回调postProcessBeforeDestruction方法;

总结一下

Spring内部对象bean的生命周期管理有一套完成的体系,并遵循了设计模式中的开闭原则(开放扩展,关闭修改),如果想修改bean的相关信息,可以通过Spring提供的扩展点,如BeanPostProcessor接口去处理,这样做的好处是不需要关心Spring内部处理逻辑,扩展方便。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯