spring bean的生命周期面试回答及代码演示

前言:

在面试中经常会被问到谈谈你对spring bean生命周期的理解,如果单方面的在网站看写的博客很难理解的,最好自己写代码体会他的实现流程。

1.先了解这几个类的意思

BeanNameAware:设置bean的名称类

BeanFactoryAware:bean工厂类接口

ApplicationContextAware:上下文类

InitializingBean :初始加载bean对象类

DisposableBean:bean对象销毁类

开始代码演示

1.创建项目工程

2.pom.xml依赖引入

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima</groupId>
    <artifactId>spring_consumer</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xbean</groupId>
            <artifactId>xbean-spring</artifactId>
            <version>3.7</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</project>

3.applicationContext-user.xml文件配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amp="http://activemq.apache.org/schema/core"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jms="http://www.springframework.org/schema/jms"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd">
	<!-- spring bean生命周期执行流程 
		init-method="initMethod" :初始化方法
		destroy-method="destroyMethod":销毁bean对象方法
	-->
    <bean id="userService" class="com.itheima.service.UserService" init-method="initMethod" destroy-method="destroyMethod"/>
    <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
    <bean id="userSerivceImpl" class="com.itheima.service.impl.UserSerivceImpl"/>

</beans>

4.编写UserService服务类

package com.itheima.service;

import java.util.Arrays;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class UserService implements BeanNameAware,
BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{

	// 对应<bean id="userService" />
	public void setBeanName(String name) {
		System.out.println("【步骤2】实现BeanNameAware接口,执行setBeanName方法,beanName值:userService");
	}
	
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("【步骤3】实现BeanFactoryAware接口,执行setBeanFactory()方法");
	}
	
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		String deanDefinitionNames = Arrays.toString(applicationContext.getBeanDefinitionNames());
		System.out.println("【步骤4】实现ApplicationContextAware接口,执行setApplicationContext方法  调用deanDefinitionNames="+deanDefinitionNames);
	}
	
	//通过注解@PostConstruct自定义初始化方法
	@PostConstruct
	public void initPostConstruct(){
		System.out.println("【步骤6】通过注解@PostConstruct自定义initPostConstruct()【初始化方法1】");
	}
	
	public void afterPropertiesSet() throws Exception {
		System.out.println("【步骤7】实现InitializingBean初始化接口,执行afterPropertiesSe()方法执行【初始化方法2】");
	}
	
	//通过<bean>自定义init-method属性指定的初始化方法
    public void initMethod() throws Exception {
        System.out.println("【步骤8】执行spring配置文件bean标签的init-method属性【初始化方法2】");
    }
    //通过注解@PreDestroy自定义销毁方法
    @PreDestroy
    public void preDestroy(){
    	System.out.println("【步骤10】通过注解@PreDestroy自定义销毁方法preDestroy()【销毁方法1】");
    }
    //销毁bean对象
    public void destroy() throws Exception {
		System.out.println("【步骤11】实现DisposableBean接口的destroy()【销毁方法2】");
	}
	 //通过<bean>自定义destroy-method属性指定的销毁方法
    public void destroyMethod() throws Exception {
        System.out.println("【步骤12】执行spring配置文件bean标签的destroy-method属性指定的【销毁方法3】");
    }
	
}

5.编写UserServiceImpl实现类

package com.itheima.service.impl;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class UserSerivceImpl implements BeanPostProcessor{
	
	//Before前置初始化方法
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("【步骤5】实现类UserSerivceImpl实现BeanPostProcessor接口,执行postProcessBeforeInitialization()前置方法");
		return bean;
	}

	//After后置初始化方法
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("【步骤9】实现类UserSerivceImpl实现BeanPostProcessor接口,执行postProcessAfterInitialization()后置方法");
		return bean;
	}
}

6.编写测试类测试bean执行顺序

package com.itheima.service;

import org.apache.xbean.spring.context.ClassPathXmlApplicationContext;

public class TestBean {

	public static void main(String[] args) {
		/**
		 * 当程序加载运行时会根据spring中配置文件找到bean配置的属性和方法,
		 * 并通过java反射机制创建实例化bean对象;
		 */
		System.out.println("【步骤1】程序运行时,加载spring配置文件,实例化bean对象");
		ClassPathXmlApplicationContext contetx =new ClassPathXmlApplicationContext("applicationContext-user.xml");
		UserService user = contetx.getBean("userService",UserService.class);
		contetx.close();
		System.out.println("【步骤13】关闭spring bean容器contetx.close()");
	}
}

7.输出结果

【步骤1】程序运行时,加载spring配置文件,实例化bean对象
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
【步骤2】实现BeanNameAware接口,执行setBeanName方法,beanName值:userService
【步骤3】实现BeanFactoryAware接口,执行setBeanFactory()方法
【步骤4】实现ApplicationContextAware接口,执行setApplicationContext方法  调用deanDefinitionNames=[userService, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0, userSerivceImpl]
【步骤5】实现类UserSerivceImpl实现BeanPostProcessor接口,执行postProcessBeforeInitialization()前置方法
【步骤6】通过注解@PostConstruct自定义initPostConstruct()【初始化方法1】
【步骤7】实现InitializingBean初始化接口,执行afterPropertiesSe()方法执行【初始化方法2】
【步骤8】执行spring配置文件bean标签的init-method属性【初始化方法2】
【步骤9】实现类UserSerivceImpl实现BeanPostProcessor接口,执行postProcessAfterInitialization()后置方法
【步骤10】通过注解@PreDestroy自定义销毁方法preDestroy()【销毁方法1】
【步骤11】实现DisposableBean接口的destroy()【销毁方法2】
【步骤12】执行spring配置文件bean标签的destroy-method属性指定的【销毁方法3】
【步骤13】关闭spring bean容器contetx.close()

8.在初始化阶段,有个特别重要的接口BeanPostProcessor,在初始化前、后调用

postProcessBeforeInitialization();//Before初始化前调用方法

postProcessAfterInitialization()//After初始化后调用方法

8.1实现流程图

9.初始化方式有三个,分别是

  1. InitializingBean类的afterPropertiesSet方法
  2. PostConstruct注解标注的方法
  3. spring配置文件applicationContext-user.xml的init-method="initMethod"

10.销毁方式有三个,分别是

  1. preDestroy注解标注的方法
  2. DisposableBean接口的destroy方法
  3. spring配置文件applicationContext-user.xml的配置的destroy-method=;"destroyMethod"

11.面试回答总结

1.根据程序加载运行输出结果回答:

【步骤1】程序运行时,加载spring配置文件,实例化bean对象
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
【步骤2】实现BeanNameAware接口,执行setBeanName方法,beanName值:userService
【步骤3】实现BeanFactoryAware接口,执行setBeanFactory()方法
【步骤4】实现ApplicationContextAware接口,执行setApplicationContext方法  调用deanDefinitionNames=[userService, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0, userSerivceImpl]
【步骤5】实现类UserSerivceImpl实现BeanPostProcessor接口,执行postProcessBeforeInitialization()前置方法
【步骤6】通过注解@PostConstruct自定义initPostConstruct()【初始化方法1】
【步骤7】实现InitializingBean初始化接口,执行afterPropertiesSe()方法执行【初始化方法2】
【步骤8】执行spring配置文件bean标签的init-method属性【初始化方法2】
【步骤9】实现类UserSerivceImpl实现BeanPostProcessor接口,执行postProcessAfterInitialization()后置方法
【步骤10】通过注解@PreDestroy自定义销毁方法preDestroy()【销毁方法1】
【步骤11】实现DisposableBean接口的destroy()【销毁方法2】
【步骤12】执行spring配置文件bean标签的destroy-method属性指定的【销毁方法3】
【步骤13】关闭spring bean容器contetx.close()

面试回答:

1.当程序加载运行时会根据spring中配置文件找到bean配置的属性和方法,并通过java反射机制创建实例化bean对象。

Bean实现了BeanNameAware接口,执行了setBeanName方法,实现注入对象。

2.实现了BeanFactoryAware工厂接口,执行了setBeanFactory方法。

3.实现了ApplicationContext接口类,执行了setsetApplicationContest方法。

4.实现了BeanPostProcessor接口类,执行postProcessBeforeInitialization方法

5.实现了InitiliazingBean 执行afterPropertiesSet方法,并加载配置文件定义了init-method 则执行对应初始化方法BeanPostProcessor 执行postProcessorfterInitilization方法,完成  Bean的初始化,使得bean可以使用。

6.实现了DisposabileBean接口,加载配置文件中的destroy-method方法销毁bean对象实例。

简要回答:

  1. 程序加载时创建bean的实例化对象。
  2. 注入bean的相关实现接口管理bean对象。
  3. 初始化bean对象。
  4. 关闭并销毁bean实例化对象。

参考案例:https://blog.csdn.net/cool_summer_moon/article/details/106149339

写的有不足的地方欢迎同行评论提出观点,谢谢!!

  • 16
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唂雨云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值