JAVA——Bean的生命周期

总览

  • 通过BeanDefinition获取bean的定义信息
  • 调用构造函数实例化bean
  • bean的依赖注入
  • 处理Aware接口(BeanNameAware、BeanFactoryAware、ApplicationContextAware)
  • Bean的后置处理器BeanPostProcessor-前置
  • 初始化方法(InitializingBean、init-method)
  • Bean的后置处理器BeanPostProcessor-后置
  • 销毁bean

20230915152849

具体介绍

BeanDefinition

在Spring容器中,每个Bean都有一个对应的BeanDefinition,BeanDefinition包含了Bean的元数据信息,如Bean的类名、作用域、构造函数、依赖关系等。这些信息通常由配置文件(如XML或JavaConfig)或注解定义。

构造函数

Spring容器根据BeanDefinition中的信息,使用Java反射机制来实例化Bean对象。这是Bean的实例化阶段,它会调用Bean类的构造函数来创建一个新的Bean实例。

依赖注入

一旦Bean实例化完成,Spring容器会根据BeanDefinition中的依赖关系,注入其他Bean或依赖的属性。这是通过构造函数注入、Setter方法注入或字段注入(@Autowired)来完成的。

public class UserService {
    private UserRepository userRepository;

    // 构造函数注入
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // ...
}

public class UserService {
    private UserRepository userRepository;

    // Setter方法注入
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // ...
}

public class UserService {
    @Autowired // 字段注入
    private UserRepository userRepository;

    // ...
}

Aware接口

如果Bean实现了Aware接口,Spring容器会将相关的信息传递给Bean,例如Bean的名称(BeanNameAware)、BeanFactory(BeanFactoryAware)、应用程序上下文(ApplicationContextAware)。这些回调方法允许Bean获取与容器相关的信息。

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class MyBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {
    private String beanName;
    private BeanFactory beanFactory;


    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }

    public void displayBeanName() {
        System.out.println("Bean Name: " + beanName);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public void displayBeanFactoryInfo() {
        String message = "BeanFactory: " + beanFactory.toString();
        System.out.println(message);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public void displayApplicationContextInfo() {
        String message = "ApplicationContext: " + applicationContext.toString();
        System.out.println(message);
    }
}

后置处理器#before

如果在容器中注册了BeanPostProcessor接口的实现类,Spring容器会在Bean的初始化前(在调用初始化方法之前)调用这些后置处理器的前置方法。这提供了在Bean初始化前执行自定义逻辑的机会。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class CustomBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 在Bean初始化前执行的逻辑
        System.out.println("BeforeInitialization: Bean '" + beanName + "' is about to be initialized.");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 在Bean初始化后执行的逻辑
        System.out.println("AfterInitialization: Bean '" + beanName + "' has been initialized.");
        return bean;
    }
}

初始化方法

Bean的初始化阶段包括两个部分:首先,Spring容器会检查Bean是否实现了InitializingBean接口,如果实现了,会调用其afterPropertiesSet方法。其次,如果在BeanDefinition中配置了自定义的初始化方法(使用init-method属性),则容器会在依赖注入完成后调用该方法。这允许开发人员在Bean初始化时执行特定的业务逻辑。

import org.springframework.beans.factory.InitializingBean;

public class MyBean implements InitializingBean {
    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 实现InitializingBean接口的初始化方法
        System.out.println("InitializingBean's afterPropertiesSet method called.");
    }

    @PostConstruct //“后”“构建”
    public void customInit() {
        // 自定义初始化方法
        System.out.println("Custom initialization method called.");
    }

    public void displayMessage() {
        System.out.println("Message: " + message);
    }
}

InitializingBean's afterPropertiesSet method called.
Custom initialization method called.

后置处理器#after

与前置处理器相反,后置处理器在Bean初始化后(在调用初始化方法之后)被调用。后置处理器可以用于执行一些额外的操作,例如对Bean进行包装或修改。

在后置处理中处理了包括:AOP【AnnotationAwareAspectJAutoProxyCreator】
AnnotationAwareAspectJAutoProxyCreator 是Spring AOP的一部分,它允许开发人员使用注解(如@Aspect、@Before、@After等)来定义切面和通知,而不必显式创建代理对象。
当Spring容器检测到一个Bean类上使用了@Aspect注解时,它会自动创建代理对象,将切面逻辑织入到目标Bean的方法中。这样,切面逻辑就可以在目标方法执行前、后或抛出异常时被调用,而不需要手动创建代理。

销毁Bean

当Bean不再被容器使用或容器关闭时,Spring容器会调用Bean的销毁方法。销毁方法可以通过实现DisposableBean接口的destroy方法来定义,也可以通过配置BeanDefinition中的自定义销毁方法(使用destroy-method属性)来指定,还可以使用@PreDestroy注解来定义Bean的销毁方法。

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

@Configuration
public class AppConfig {

    @Bean(initMethod = "init", destroyMethod = "customDestroy")
    public MyBean myBean() {
        return new MyBean();
    }
}

import javax.annotation.PreDestroy;

public class MyBean {

    public MyBean() {
        System.out.println("MyBean constructor called.");
    }

    public void customDestroy() {
        // 自定义销毁方法
        System.out.println("Custom destroy method called.");
    }

    @Override
    public void destroy() throws Exception {
        // 实现DisposableBean接口的销毁方法
        System.out.println("DisposableBean's destroy method called.");
    }
    @PreDestroy
    public void preDestroy() {
        // 使用@PreDestroy注解定义销毁方法
        System.out.println("@PreDestroy annotated method called.");
    }
}

posted @ 2023-09-15 19:15  岸南  阅读(76)  评论(0)    收藏  举报