Spring进阶-Bean生命周期(下)

背景

本文为Bean生命周期的一个总结文章,阅读该文推荐先看之前写的《Spring进阶-Bean生命周期(上)》和《Spring进阶-BeanPostProcessor》两篇文章。

前面我们已经主要的讲了Bean生命周期的主要四个过程:实例化、属性赋值、初始化和销毁。同时在前面我们还讲了什么是BeanPostProcessor,以及Spring中部分功能是怎么通过BeanPostProcessor实现的。
从前面的了解我们也发现,在Bean的生命周期中有很多BeanPostProcessor的影子,所以本文主要内容就是结合BeanPostProcessor对Bean生命周期做一个系统化的说明。

示例

public class LifeCycleDemo4 {
    public static void main(String[] args) {
        String printfTemplate = "=========== [%s] ===========%n";

        System.out.printf(printfTemplate,"创建BeanFactory");
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        System.out.printf(printfTemplate,"注册BeanPostProcessor");
        factory.addBeanPostProcessor(new AllBeanPostProcessor());
        System.out.printf(printfTemplate,"注册AllBeanPostProcessor完成");
        factory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
        System.out.printf(printfTemplate,"注册CommonAnnotationBeanPostProcessor完成");
        System.out.printf(printfTemplate,"创建BeanDefinition");
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Student.class)
                .addPropertyValue("name", "mac")
                .addPropertyValue("classNo", "1班")
                .setInitMethodName("initMethod")
                .setDestroyMethodName("destroyMethod")
                .getBeanDefinition()
;
        System.out.printf(printfTemplate,"注册BeanDefinition");
        factory.registerBeanDefinition("student",beanDefinition);
        System.out.printf(printfTemplate,"创建Bean");
        Student student = factory.getBean("student", Student.class);
        System.out.println("打印Bean信息:"+student);
        System.out.printf(printfTemplate,"销毁Bean");
        factory.destroyBean("student", student);

    }
}

class Student implements InitializingBeanDisposableBean {

    private String name;
    private String classNo;

    public Student() {
        System.out.println("new Student()");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("设置name为:"+name);
        this.name = name;
    }

    public String getClassNo() {
        return classNo;
    }

    public void setClassNo(String classNo) {
        System.out.println("设置classNo为:"+classNo);
        this.classNo = classNo;
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("@PostConstruct方法");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("@PreDestroy方法");
    }


    public void initMethod() {
        System.out.println("执行BeanDefinition中定义的initMethod方法");
    }

    public void destroyMethod() {
        System.out.println("执行BeanDefinition中定义的destroyMethod方法");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean#destroy");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean#afterPropertiesSet");
    }
}

class AllBeanPostProcessor implements BeanPostProcessorMergedBeanDefinitionPostProcessorInstantiationAwareBeanPostProcessorDestructionAwareBeanPostProcessor {

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        System.out.println("DestructionAwareBeanPostProcessor#postProcessBeforeDestruction => 销毁前调用");
    }

    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        System.out.println("MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition => 合并BeanDefinition后调用");
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation => 实例化前调用");
        //如果该方法返回值不为空,则Bean不会进行后面的生命周期
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation => 实例化后调用");
        //返回值代表是否应该对Bean进行属性赋值,如果返回false则不会对Bean进行属性赋值
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor#postProcessProperties => 属性赋值还未应用前调用");
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor#postProcessBeforeInitialization => 初始化前调用");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor#postProcessAfterInitialization => 初始化后调用");
        return bean;
    }
}

运行上面代码,最后打印结果如下:

=========== [创建BeanFactory] ===========
=========== [注册BeanPostProcessor] ===========
=========== [注册AllBeanPostProcessor完成] ===========
=========== [注册CommonAnnotationBeanPostProcessor完成] ===========
=========== [创建BeanDefinition] ===========
=========== [注册BeanDefinition] ===========
=========== [创建Bean] ===========
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation => 实例化前调用
new Student()
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition => 合并BeanDefinition后调用
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation => 实例化后调用
InstantiationAwareBeanPostProcessor#postProcessProperties => 属性赋值还未应用前调用
设置name为:mac
设置classNo为:1班
BeanPostProcessor#postProcessBeforeInitialization => 初始化前调用
@PostConstruct方法
InitializingBean#afterPropertiesSet
执行BeanDefinition中定义的initMethod方法
BeanPostProcessor#postProcessAfterInitialization => 初始化后调用
打印Bean信息:com.buydeem.share.lifecycle.Student@290dbf45
=========== [销毁Bean] ===========
DestructionAwareBeanPostProcessor#postProcessBeforeDestruction => 销毁前调用
@PreDestroy方法
DisposableBean#destroy
执行BeanDefinition中定义的destroyMethod方法

上面结果展示了Bean的生命周期和BeanPostProcessor回调内容。首先我们创建了BeanFactory即IOC容器,接着我们将自己创建的AllBeanPostProcessor和Spring提供的CommonAnnotationBeanPostProcessor注册到容器,再然后我们调用方法让容器创建Bean和销毁Bean。通过上面的打印结果,我们可以画出Bean生命周期和BeanPostProcessor回调的流程图,如下所示:

Spring进阶-Bean生命周期(下)
Bean生命周期和BeanPostProcessor

总结

本文的主要内容就是对Bean生命周期和BeanPostProcessor的一个总结。在学习Bean生命周期时我们还是要结合BeanPostProcessor一块学习,所以在阅读本文时我建议你阅读前面所写的《Spring进阶-Bean生命周期(上)》《Spring进阶-BeanPostProcessor》两篇文章。在阅读完这三篇文章之后,我认为你应该知道以下几点:

  • Bean的整个生命周期
  • BeanPostProcessor及其子类的功能以及回调时机
  • Aware相关接口的实现原理
  • @PostConstruct@PreDestroy注解实现原理
  • @Autowired@Value等依赖注入原理

上面这些内容在上面的两篇文章中都有涉及。

学习建议

授人以鱼不如授人以渔

可能有的小伙伴不知道如何去阅读Spring的源码,我大致说一下我平时如何阅读这些源码。

  • 首先Spring是一个很庞大的家伙,它包含了很多模块,但是我们最先需要了解的就是Spring的IOC和AOP这两个重点。所以在学习时我们只需要依赖Spring核心模块,对于像数据库事务、SpringMVC等等内容我们都不要添加进来,这些内容会让你觉得内容太多容易有惧怕感。通常我个人在学习Spring的源码过程中,我的工程基本上只会添加spring-context依赖。
  • 其次对于Spring的核心功能至少要知道如何使用。对于功能和用法都不清楚,想要看源码我个人建议不要浪费时间。
  • 看源码不能真的只是看,应该写示例代码跟踪断点调试。在看源码时有可能有很多细节你暂时看不懂,这时候你不能太纠结一些细节处,你应该抓住整个过程的主要节点。通过主要节点你能知道这个过程在做一件什么事,然后再细分节点查看分析。
  • 接口很重要。在Spring中有很多接口,接口代表的能力。例如BeanFactory就是一个接口,它代表了它的实现类具有基础的IOC容器能力。而BeanFactory的子接口则是对IOC容器能力的补充,这些接口通过组合继承等方式来丰富SpringIOC的功能。
  • 能熟练的使用编辑器。这里面的熟练是指你至少知道如何查看一个接口的所有实现类,如何查看一个类的UML等。这些功能能让你将这些看起来杂乱无章的类关联起来,对于它们之间的关系能通过图形化的形式展现出来。

上面的内容都是本人基于自己的学习过程中的一些小建议,希望能对你有帮助。最后还是一句话多动手,看文章不能让你真正的明白其中的原理,只有自己亲自动手才能真正理解。欢迎关注公众号,我会不定期的去更新我自己学习Spring源码的相关文章。

原文始发于微信公众号(一只菜鸟程序员):Spring进阶-Bean生命周期(下)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/72977.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!