Spring Bean生命周期学习

文章参考地址,补充并优化了些内容

1. 概述

  1. 什么是Bean

被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。

  1. 创建Bean的方式

Spring提供xml配置、注解配置或Java配置来实现Bean的创建和注入

  1. 与IoC容器的关系

Spring IoC(ApplicationContext)容器负责进行扫描Bean、进行Bean的初始化、配置和依赖管理

2. 相关注解

  1. 声明Bean的注解
  • @Component 没有明确角色的组件
  • @Service 在业务逻辑层使用
  • @Repository 在数据访问层使用
  • @Controller 在控制层使用
  • @RestController 本质上是@Controller + @ResponseBody的组合
  • @Configuration 和Component类似,但其所有带 @Bean 注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例
  1. 其他
  • @Scope 指定Bean的作用域

    • singleton:Spring 容器中有且只有一个Bean实例,只要Spring容器不销毁或退出,该Bean实例就会一直存活
    • prototype:每次获取Bean的时候会有一个新的实例,Spring容器不能对返回Bean实例的整个生命周期负责
    • request:request只适用于Web程序,每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,当请求结束后,该对象的生命周期即告结束
    • session:session只适用于Web程序,session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
    • application:application只适用于Web程序,全局作用域
  • @Bean 方法级别的Bean,一般和 @Configuration 使用,默认情况下beanName与方法名相同

  • @PostConstruct 指定initMethod,对应XML配置中的 init-method

  • @PreDestroy 指定destroyMethod,对应XML配置中的 destroy-method

3. Bean的生命周期

宏观上来说Bean的生命周期分为:定义、初始化、使用、销毁。从代码角度拆开来看,如下。

流程图

在这里插入图片描述

序列图

在这里插入图片描述

4. 演示

演示涉及五个模块的代码,分别是Spring启动类、Bean对象、BeanFactoryPostProcessor、BeanPostProcessor、InstantiationAwareBeanPostProcessorAdapter

4.1 User.java
@Component
public class User implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
    
    
    private String name;

    private BeanFactory beanFactory;
    private String beanName;

    public User() {
    
    
        System.out.println("【构造器】调用User的构造器实例化");
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        System.out.println("【注入属性】注入属性name");
        this.name = name;
    }

    /**
     * 通过<bean>的init-method属性指定的初始化方法
     */
    @PostConstruct
    public void userInit() {
    
    
        System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");
    }

    /**
     * 这是BeanFactoryAware接口方法
     *
     * @param beanFactory
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
    
    
        System.out.println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
        this.beanFactory = beanFactory;
    }

    /**
     * 这是BeanNameAware接口方法
     *
     * @param beanName
     */
    @Override
    public void setBeanName(String beanName) {
    
    
        System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
        this.beanName = beanName;
    }

    /**
     * 这是InitializingBean接口方法
     */
    @Override
    public void afterPropertiesSet() {
    
    
        System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
    }

    /**
     * 这是DisposableBean接口方法
     */
    @Override
    public void destroy() {
    
    
        System.out.println("【DisposableBean接口】调用Disposable.destroy()");
    }

    /**
     * 通过<bean>的destroy-method属性指定的初始化方法
     */
    @PreDestroy
    public void userDestroy() {
    
    
        System.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法");
    }

    @Override
    public String toString() {
    
    
        final StringBuilder sb = new StringBuilder("User{");
        sb.append("name='").append(name).append('\'');
        sb.append('}');
        return sb.toString();
    }
}
4.2 MyBeanFactoryPostProcessor.java
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    
    public MyBeanFactoryPostProcessor() {
    
    
        super();
        System.out.println("这是BeanFactoryPostProcessor实现类构造器");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) {
    
    
        System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
        BeanDefinition bd = arg0.getBeanDefinition("user");
        bd.getPropertyValues().addPropertyValue("name", "picheng");
    }
}
4.3 MyBeanPostProcessor.java
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    
    public MyBeanPostProcessor() {
    
    
        super();
        System.out.println("这是BeanPostProcessor实现类构造器!");
    }

    @Override
    public Object postProcessAfterInitialization(Object arg0, String arg1) {
    
    
        System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
        return arg0;
    }

    @Override
    public Object postProcessBeforeInitialization(Object arg0, String arg1) {
    
    
        System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
        return arg0;
    }
}
4.4 MyInstantiationAwareBeanPostProcessor.java
@Component
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
    
    
    public MyInstantiationAwareBeanPostProcessor() {
    
    
        super();
        System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
    }

    /**
     * 接口方法、实例化Bean之前调用
     */
    @Override
    public Object postProcessBeforeInstantiation(Class beanClass,
                                                 String beanName) {
    
    
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
        return null;
    }

    /**
     * 接口方法、实例化Bean之后调用
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
    
    
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
        return bean;
    }

    /**
     * 接口方法、设置某个属性时调用
     */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    
    
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
        return pvs;
    }
}
4.5 DemoApplication.java
@SpringBootApplication
public class DemoApplication {
    
    

    public static void main(String[] args) {
    
    
        System.out.println("现在开始初始化容器");

        ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        System.out.println("容器初始化成功");
        // get user,并使用
        User user = context.getBean("user", User.class);
        System.out.println(user);

        System.out.println("现在开始关闭容器!");
        ((ConfigurableApplicationContext) context).close();
    }
}
4.6 运行程序,查看运行结果

由于打印日志较多,只截取重要信息

现在开始初始化容器

// Porcessor初始化
这是BeanFactoryPostProcessor实现类构造器
BeanFactoryPostProcessor调用postProcessBeanFactory方法
这是BeanPostProcessor实现类构造器!
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!

// Bean初始化
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
【构造器】调用User的构造器实例化
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
【注入属性】注入属性name
【BeanNameAware接口】调用BeanNameAware.setBeanName()
【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!
【init-method】调用<bean>的init-method属性指定的初始化方法
【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
容器初始化成功

// Bean使用
User{
    
    name='picheng'}

// Bean销毁
现在开始关闭容器!
【destroy-method】调用<bean>的destroy-method属性指定的初始化方法
【DisposableBean接口】调用Disposable.destroy()

猜你喜欢

转载自blog.csdn.net/Dkangel/article/details/108201709
今日推荐