探索Spring系列(一)Spring容器和Bean的生命周期

前言

不知不觉毕业已经三年有余,前面的时间一直忙于工作上的事情,最近稍微有点空闲时间,就准备梳理下自己的知识体系,发觉得自己的知识体系很是混乱和不足,正巧手中有一些书籍,借此机会好好学习和梳理一番,也希望自己的一点小小记录能分享给各位,带给大家一些收获。

一:Spring容器

Spring容器负责创建,管理对象,对象的整个生命周期都是由容器(container)负责的,下面是Spring中容器的接口的实现类

我们在开发中接触和使用最多的就是其中的基于注解的配置类的AnnotationConfigWebApplicationContext上下文,和基于xml配置的XmlWebApplicationContext上下文,当然Spring容器的还要一个重要的功能DI(依赖注入)这个功能我将在下个章节学习

二:Bean的生命周期

了解Bean的生命周期,有助于我们理解Bean在容器的运作过程,何时创建,何时调用,何时销毁, spring对Bean实例化过程主要有以下几个阶段:

1:spring对bean进行实例化
2:spring将值和bean的引用注入到bean的对应属性中
3:如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()方法
4:如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
5:如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传递进来
6:如果bean实现了BeanPostProcessor接口,Spring将调用它的postProcessorBeforeInitialization()q前置处理方法
7:如果bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方方法,类似的如果bean使用了init-method声明了初始化方法,该方法也会被调用
8:如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessorAfterInitialization()后置处理方法
9:此时bean已经准备就虚了,可以被应用程序使用了,它们将一直驻留在应用程序上下文中,直到该应用上下文被销毁
10:如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法,同样,如果bean使用了destroy-method声明了销毁方法,该方法也会被调用

下面我们实际写代码测试一下

首先我们定义一个实体类并且实现eanNameAware, BeanFactoryAware,ApplicationContextAware, InitializingBean, BeanPostProcessor, DisposableBean接口重写父类的方法

package com.lly.springtest1.entity;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @ClassName GirlFriendEntity
 * @Description bean实体类
 * @Author lly
 * @Date 2019/1/16
 * @Version 1.0
 **/
@Slf4j
public class GirlFriendEntity implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {

    private String name;


    public GirlFriendEntity() {
        log.info("调用GirlFriendEntity的无参数构造器方法");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        log.info("BeanFactoryAware调用setBeanFactory方法将BeanFactory实例传入");
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        log.info("对name属性进行赋值");
        this.name = name;
    }

    @Override
    public void setBeanName(String s) {
        log.info("BeanNameAware调用setBeanName方法,将bean的name注入");
    }

    @Override
    public void destroy() throws Exception {
        log.info("DisposableBean调用destroy方法");

    }

    @Override
    public void afterPropertiesSet() throws Exception {

        log.info("InitializingBean调用afterPropertiesSet方法");
    }

    //自定义的初始化方法
    @PostConstruct
    public void myInit() {
        log.info("调用自定义的init方法");
    }

    //自定义销毁方法
    @PreDestroy
    public void myDestroy() {
        log.info("调用自定义的destroy方法");
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("调用ApplicationContext方法的setApplicationContext注入上下文");
    }
}

复制代码

接着我们来定义个继承BeanPostProcessor的类来观察

package com.lly.springtest1.entity;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * @ClassName MyBeanPostProcessor
 * @Description
 * @Author lly
 * @Date 2019/1/16
 * @Version 1.0
 **/
@Slf4j
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean.getClass() == GirlFriendEntity.class) {
            log.info("BeanPostProcessor调用postProcessBeforeInitialization");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean.getClass() == GirlFriendEntity.class) {
            log.info("BeanPostProcessor调用postProcessAfterInitialization");
        }
        return bean;
    }

}

复制代码

然后启动容器看看bean初始化的具体流程

package com.lly.springtest1.entity;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ClassName Test
 * @Description 
 * @Author lly
 * @Date 2019/1/16
 * @Version 1.0
 **/
@Configuration
public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Test.class);
        context.close();
    }

    @Bean
    public MyBeanPostProcessor getBean() {
        return new MyBeanPostProcessor();
    }

    @Bean
    public GirlFriendEntity getGirl() {
        GirlFriendEntity girl = new GirlFriendEntity();
        girl.setName("颖宝");
        return girl;
    }
}

复制代码

打印结果如下

我们可以清晰看到bean的整个生命周期

另外关于自定义初始化和销毁的方法除了有上述的注解方式,还可以使用这种方式,效果是一样

转载于:https://juejin.im/post/5c3c00eae51d45522578e815

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值