Aprendizaje del ciclo de vida de Spring Bean

Dirección de referencia del artículo , complementado y optimizado algunos contenidos.

1. Información general

  1. Que es Bean

Los objetos llamados beans son la columna vertebral de la aplicación y son administrados por el contenedor Spring IoC. Un bean es un objeto que crea una instancia, ensambla y administra el contenedor Spring IoC.

  1. La forma de crear Bean

Spring proporciona configuración xml, configuración de anotaciones o configuración de Java para realizar la creación e inyección de Bean

  1. Relación con el contenedor de IoC

El contenedor Spring IoC (ApplicationContext) es responsable de escanear Beans, inicialización de Bean, configuración y administración de dependencias

2. Notas relacionadas

  1. Declarar la anotación de Bean
  • @Component Componentes sin un rol claro
  • @Service Utilizado en la capa de lógica empresarial
  • @Repository Usar en la capa de acceso a datos
  • @Controller Usar en la capa de control
  • @RestController Esencialmente una combinación de @Controller + @ResponseBody
  • @Configuration Componente y similar , pero con todos los @Beanmétodos anotados será proxy dinámico, por lo que la llamada es la misma instancia del método devuelve
  1. otro
  • @Scope Especificar el alcance del Bean

    • singleton: Hay una y solo una instancia de Bean en el contenedor de Spring. Siempre que el contenedor de Spring no se destruya o salga, la instancia de Bean siempre sobrevivirá
    • prototype: Habrá una nueva instancia cada vez que se obtenga un Bean, y el contenedor Spring no puede ser responsable de todo el ciclo de vida de la instancia de Bean devuelta.
    • request: La solicitud solo es aplicable a programas Web, cada solicitud HTTP generará un nuevo bean, y el bean solo es válido en la solicitud HTTP actual.Cuando finaliza la solicitud, el ciclo de vida del objeto finaliza.
    • session: La sesión solo es aplicable a los programas Web. El alcance de la sesión significa que se generará un nuevo bean para cada solicitud HTTP, y el bean solo es válido en la sesión HTTP actual.
    • application: La aplicación solo se aplica a programas web, alcance global
  • @Bean Los beans de nivel de método se utilizan generalmente con @Configuration. De forma predeterminada, el beanName es el mismo que el nombre del método

  • @PostConstruct Especifique initMethod, correspondiente a init-method en la configuración XML

  • @PreDestroy Especifique destroyMethod, correspondiente a destroy-method en la configuración XML

3. Ciclo de vida del frijol

Macroscópicamente hablando, el ciclo de vida de un Bean se divide en: definición, inicialización, uso y destrucción. Desde el punto de vista del código, es el siguiente.

diagrama de flujo

Inserte la descripción de la imagen aquí

Diagrama de secuencia

Inserte la descripción de la imagen aquí

4. Demostración

La demostración incluye el código de cinco módulos, a saber, clase de arranque Spring, objeto Bean, BeanFactoryPostProcessor, BeanPostProcessor, InstantiationAwareBeanPostProcessorAdapter

4.1 Usuario.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 Ejecute el programa y vea los resultados

Debido a la gran cantidad de registros impresos, solo se intercepta información importante

现在开始初始化容器

// 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()

Supongo que te gusta

Origin blog.csdn.net/Dkangel/article/details/108201709
Recomendado
Clasificación