Si desea reducir la cantidad de código, configure rápidamente un Aware Spring Bean

Este artículo se comparte desde la comunidad HUAWEI CLOUD " Aware Spring Bean " por JavaLib de Chen Pi.

Frijoles de primavera conscientes

En circunstancias normales, el bean en Spring no es consciente de Spring, es decir, no puede percibir qué Bean Factory (BeanFactory) lo creó; no puede percibir su id en la fábrica, es decir, beanName; ni puede percibir Spring Application objeto de contexto (ApplicationContext) y así sucesivamente.

Si queremos que Spring Bean perciba esta información, podemos obtener esta información de alguna manera y luego establecerla en la instancia del bean. La desventaja de este método es que necesitamos obtener la información que necesitamos percibir y luego configurarla activamente en el bean, lo que escribirá una gran cantidad de código redundante. Pero la ventaja es que se puede desacoplar de Spring.

Por supuesto, el marco Spring proporciona esta extensibilidad para que un bean sea consciente. Simplemente deje que la clase de bean implemente una interfaz específica y anule los métodos en ella. De esta manera, Spring llamará a estos métodos anulados en alguna etapa del ciclo de vida del bean, inyectando la información que debe tener en cuenta. La desventaja de este método es que necesita ser acoplado con Spring, la ventaja es que puede reducir la cantidad de código y es simple.

Interfaz consciente

Para que los beans en Spring adquieran cierta conciencia, necesitan implementar interfaces específicas, que tengan una interfaz principal común, la interfaz Aware.

package org.springframework.beans.factory;

public interface Aware {
 
}

Aware es una interfaz de marcador que indica que un bean puede obtener un objeto específico en el contenedor Spring a través de métodos de devolución de llamada. La firma del método específico está definida por las subinterfaces individuales, pero generalmente debe contener solo un método que acepte un solo parámetro y devuelva void.

Tenga en cuenta que solo implementar la interfaz Aware no proporcionará la funcionalidad predeterminada. Generalmente implementamos subinterfaces de Aware para obtener capacidades de percepción específicas.

Hay muchas subinterfaces de la interfaz Aware, como BeanNameAware, BeanFactoryAware, ApplicationContextAware, EnvironmentAware, ApplicationEventPublisherAware, etc. Estos son algunos usos comunes.

Interfaz BeanNameAware

Si el bean necesita conocer su propio beanName en la fábrica de beans, es decir, el nombre (identidad) en el contenedor Spring. Esta interfaz BeanNameAware se puede implementar. El código fuente de la interfaz BeanNameAware es el siguiente, solo hay un método y el beanName se establecerá en el bean a través de este método.

package org.springframework.beans.factory;

public interface BeanNameAware extends Aware {
	void setBeanName(String name);
}

De hecho, el bean que usamos generalmente no necesita saber su nombre en beanFactory, lo cual tiene poca importancia. Generalmente el uso oficial del framework propio de Spring es más, y el oficial no nos recomienda usarlo, porque esto hará que los beans dependan de la API de Spring.

package com.chenpi;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;

/**
 * @author 陈皮
 * @version 1.0
 * @description
 * @date 2022/4/3
 */
@Component
public class Person implements BeanNameAware {

  private String beanName;

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

  public String getBeanName() {
    return beanName;
  }
}

Escriba una unidad de prueba que verifique lo siguiente:

package com.chenpi;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ApplicationTests {

  @Autowired
  private Person person;

  @Test
  public void testValue() {
    System.out.println("Person BeanName:" + person.getBeanName());
  }

}

// 输出结果如下
Person BeanName:person

Interfaz BeanFactoryAware

Si el Bean quiere configurar su propio objeto BeanFactory, puede implementar la interfaz BeanFactoryAware. Si es necesario, los beans pueden obtener otros objetos de bean a través del objeto BeanFactory para la colaboración. Por supuesto, este método no se recomienda, se recomienda usar el método DI para inyectar objetos de frijol dependientes. El código fuente de la interfaz BeanFactoryAware es el siguiente:

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;

public interface BeanFactoryAware extends Aware {

    // 在bean属性填充之后,但是在初始回调(例如afterPropertiesSet()方法)之前回调此方法
	void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}

Los resultados de la verificación del código de prueba y de la prueba unitaria son los siguientes:

package com.chenpi;

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.stereotype.Component;

/**
 * @author 陈皮
 * @version 1.0
 * @description
 * @date 2022/4/3
 */
@Component
public class Person implements BeanNameAware, BeanFactoryAware {

  private String beanName;
  private BeanFactory beanFactory;

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

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

  public String getBeanName() {
    return beanName;
  }

  public BeanFactory getBeanFactory() {
    return beanFactory;
  }
}
package com.chenpi;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ApplicationTests {

  @Autowired
  private Person person;

  @Test
  public void testValue() {
    System.out.println("Person BeanName:" + person.getBeanName());
    System.out.println("Person Bean's BeanFactory:" + person.getBeanFactory().getClass());
    System.out.println(
        person == person.getBeanFactory().getBean(person.getBeanName(), Person.class));
  }

}

// 输出结果如下
Person BeanName:person
Person Bean's BeanFactory:class org.springframework.beans.factory.support.DefaultListableBeanFactory
true

Interfaz ApplicationContextAware

Si Spring Bean necesita conocer el contenedor Spring, es decir, el objeto ApplicationContext, puede implementar la interfaz ApplicationContextAware. Se pueden obtener otros objetos Bean a través del contenedor Spring para colaboración.

Por supuesto, si un objeto bean necesita acceder a los recursos del archivo, como llamar al método applicationContext.getResource(), o desea publicar un evento de aplicación applicationContext.publishEvent (evento ApplicationEvent), o necesita acceder a MessageSource, este método puede ser implementado. Sin embargo, para estos escenarios específicos, es mejor implementar interfaces ResourceLoaderAware, ApplicationEventPublisherAware o MessageSourceAware más específicas.

package org.springframework.context;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;

public interface ApplicationContextAware extends Aware {

	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

Los resultados de la verificación del código de prueba y de la prueba unitaria son los siguientes:

package com.chenpi;

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.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author 陈皮
 * @version 1.0
 * @description
 * @date 2022/4/3
 */
@Component
public class Person implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {

  private String beanName;
  private BeanFactory beanFactory;
  private ApplicationContext applicationContext;

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

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

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

  public String getBeanName() {
    return beanName;
  }

  public BeanFactory getBeanFactory() {
    return beanFactory;
  }

  public ApplicationContext getApplicationContext() {
    return applicationContext;
  }
}
package com.chenpi;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;

@SpringBootTest
class ApplicationTests {

  @Autowired
  private Person person;

  @Test
  public void testValue() {
    System.out.println("Person BeanName:" + person.getBeanName());
    System.out.println("Person Bean's BeanFactory:" + person.getBeanFactory().getClass());
    System.out.println(
        person == person.getBeanFactory().getBean(person.getBeanName(), Person.class));
    ApplicationContext applicationContext = person.getApplicationContext();
    Person person1 = applicationContext.getBean(person.getBeanName(), Person.class);
    System.out.println(applicationContext.getClass());
    System.out.println(person == person1);
  }

}

// 输出结果如下
Person BeanName:person
Person Bean's BeanFactory:class org.springframework.beans.factory.support.DefaultListableBeanFactory
true
class org.springframework.web.context.support.GenericWebApplicationContext
true

Haga clic en Seguir para conocer las nuevas tecnologías de HUAWEI CLOUD por primera vez~

Supongo que te gusta

Origin blog.csdn.net/devcloud/article/details/124043234
Recomendado
Clasificación