2022Java最新面试-Bean的生命周期

1. 基础知识

1.1 什么是 IoC ?

IoC,控制反转,想必大家都知道,所谓的控制反转,就是把 new 对象的权利交给容器,所有的对象都被容器控制,这就叫所谓的控制反转。

IoC 很好地体现了面向对象设计法则之一 —— 好莱坞法则:“别找我们,我们找你”,即由 IoC 容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

理解好 IoC 的关键是要明确 “谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”。

谁控制谁,控制什么?

传统 Java SE 程序设计,我们直接在对象内部通过 new 进行创建对象,是程序主动去创建依赖对象。而 IoC 是由专门一个容器来创建这些对象,即由 IoC 容器来控制对象的创建。

谁控制谁?当然是 IoC 容器控制了对象;

控制什么?主要控制了外部资源获取(不只是对象,比如包括文件等)。

为何是反转,哪些方面反转了?

有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转,而反转则是由容器来帮忙创建及注入依赖对象。

为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;

哪些方面反转了?依赖对象的获取被反转了。

1.2 Bean 生命周期

对 Prototype Bean 来说,当用户 getBean 获得 Prototype Bean 的实例后,IOC 容器就不再对当前实例进行管理,而是把管理权交由用户,此后再 getBean 生成的是新的实例。

所以我们描述 Bean 的生命周期,都是指的 Singleton Bean。

Bean 生命周期过程:

实例化:第 1 步,实例化一个 Bean 对象;

属性赋值:第 2 步,为 Bean 设置相关属性和依赖;

初始化:初始化的阶段的步骤比较多,5、6 步是真正的初始化,第 3、4 步为在初始化前执行,第 7 步在初始化后执行,初始化完成之后,Bean 就可以被使用了;

销毁:第 8~10 步,第 8 步其实也可以算到销毁阶段,但不是真正意义上的销毁,而是先在使用前注册了销毁的相关调用接口,为了后面第 9、10 步真正销毁 Bean 时再执行相应的方法。

整个执行流程稍微有些抽象,下面我们通过代码,来演示执行流程。

1.3 执行流程

创建一个 LouzaiBean。

 

public class LouzaiBean implements InitializingBean, BeanFactoryAware, BeanNameAware, DisposableBean {

   /**

     * 姓名

     */

    private String name;

    public LouzaiBean() {

        System.out.println("1.调用构造方法:我出生了!");

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

        System.out.println("2.设置属性:我的名字叫"+name);

    }

    @Override

    public void setBeanName(String s) {

        System.out.println("3.调用BeanNameAware#setBeanName方法:我要上学了,起了个学名");

    }

    @Override

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

        System.out.println("4.调用BeanFactoryAware#setBeanFactory方法:选好学校了");

    }

    @Override

    public void afterPropertiesSet() throws Exception {

        System.out.println("6.InitializingBean#afterPropertiesSet方法:入学登记");

    }

    public void init() {

        System.out.println("7.自定义init方法:努力上学ing");

    }

    @Override

    public void destroy() throws Exception {

        System.out.println("9.DisposableBean#destroy方法:平淡的一生落幕了");

    }

    public void destroyMethod() {

        System.out.println("10.自定义destroy方法:睡了,别想叫醒我");

    }

    public void work(){

        System.out.println("Bean使用中:工作,只有对社会没有用的人才放假。。");

    }

}

自定义一个后处理器 MyBeanPostProcessor。

public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

       System.out.println("5.BeanPostProcessor.postProcessBeforeInitialization方法:到学校报名啦");

        return bean;

    }

    @Override

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("8.BeanPostProcessor#postProcessAfterInitialization方法:终于毕业,拿到毕业证啦!");

        return bean;

    }

}

applicationContext.xml 配置文件(部分)。

<bean name="myBeanPostProcessor" class="demo.MyBeanPostProcessor" />

<bean name="louzaiBean" class="demo.LouzaiBean"

      init-method="init" destroy-method="destroyMethod">

    <property name="name" value="楼仔" />

</bean>

测试入口:

public class MyTest {

    public static void main(String[] args) {

        ApplicationContext context =new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

        LouzaiBean louzaiBean = (LouzaiBean) context.getBean("louzaiBean");

        louzaiBean.work();

        ((ClassPathXmlApplicationContext) context).destroy();

    }

}

执行结果:

1.调用构造方法:我出生了!

2.设置属性:我的名字叫楼仔

3.调用BeanNameAware#setBeanName方法:我要上学了,起了个学名

4.调用BeanFactoryAware#setBeanFactory方法:选好学校了

5.BeanPostProcessor.postProcessBeforeInitialization方法:到学校报名啦

6.InitializingBean#afterPropertiesSet方法:入学登记

7.自定义init方法:努力上学ing

8.BeanPostProcessor#postProcessAfterInitialization方法:终于毕业,拿到毕业证啦!

Bean使用中:工作,只有对社会没有用的人才放假。。

9.DisposableBean#destroy方法:平淡的一生落幕了

10.自定义destroy方法:睡了,别想叫醒我

这个流程非常清晰,Bean 生命周期流程图能完全对应起来。

1.4 扩展方法

我们发现,整个生命周期有很多扩展过程,大致可以分为 4 类:

Aware 接口:让 Bean 能拿到容器的一些资源,例如 BeanNameAware 的 setBeanName(),BeanFactoryAware 的 setBeanFactory();

后处理器:进行一些前置和后置的处理,例如 BeanPostProcessor 的 postProcessBeforeInitialization() 和 postProcessAfterInitialization();

生命周期接口:定义初始化方法和销毁方法的,例如 InitializingBean 的 afterPropertiesSet(),以及 DisposableBean 的 destroy();

配置生命周期方法:可以通过配置文件,自定义初始化和销毁方法,例如配置文件配置的 init() 和 destroyMethod()。

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值