Preparación para la certificación profesional de primavera. Contenedor, IoC, Frijoles

Buen dia, Habr.


Hoy decidí presentarles una traducción de una serie de artículos en preparación para la Certificación Profesional de Primavera .


Esta traducción es solo el primer artículo, si va a la audiencia, continuaré emitiendo traducciones.


¿Por qué estoy haciendo esto, porque ya hay un montón de materiales especializados?
  1. A menudo, la información que contienen no está estructurada, no se recopila o no es relevante
  2. Los desarrolladores jóvenes pueden no saber inglés. Este ciclo se puede usar no solo para la certificación, sino también para la autoformación / repetición de materiales.
  3. Estos materiales se pueden utilizar en preparación para la entrevista, como Se organizan en forma de preguntas y respuestas.
  4. Una ventaja importante y más importante es que este control de calidad está compuesto por preguntas de la Guía de estudio fundamental oficial.

  • Deliberadamente omití algunas preguntas que me parecían superfluas o que no estaban en la guía .

Tabla de contenidos
  1. Inyección de dependencia, contenedor, IoC, frijoles
  2. AOP (programación orientada a aspectos)
  3. JDBC, Transacciones, JPA, Spring Data
  4. Bota de primavera
  5. Mvc de primavera
  6. Seguridad de primavera
  7. DESCANSO
  8. Prueba


Escribiré una lista de fuentes de las cuales el autor tomó materiales.
  • Spring 5 patrones de diseño
  • Spring in Action 4ta edición
  • Spring Security - Tercera edición
  • Certificación Core Spring 5 en detalle por Ivan Krizsan
  • Spring Documentation y Spring API javadocs

Entonces, comencemos.


¿Qué es la inyección de dependencia (DI) y cuáles son sus beneficios?

La inyección de dependencia es un patrón especial que reduce la comunicación entre los componentes de Spring. Por lo tanto, cuando aplica DI, su código se vuelve más limpio, más simple, se vuelve más fácil de entender y probar.
De acuerdo con el patrón DI, la creación de objetos para dependencias se transfiere a la fábrica o se entrega a un tercero. Esto significa que podemos centrarnos en usar estos objetos en lugar de crearlos.


DI Beneficios
  • Comunicación reducida entre partes de la aplicación.
  • Pruebas mejoradas
  • Arquitectura de aplicaciones mejorada
  • Reduce el código repetitivo
  • Estandariza el desarrollo de aplicaciones

¿Por qué se recomiendan las interfaces para crear beans Spring?
  • Pruebas mejoradas. En las pruebas, el bean se puede reemplazar con un objeto especial (simulacro o código auxiliar) que implementa la interfaz del bean.
  • Le permite usar el mecanismo de proxy dinámico del JDK (por ejemplo, al crear un repositorio a través de Spring Data)
  • Le permite ocultar la implementación

¿Qué es el contexto de la aplicación?

En Spring Framework, la interfaz org.springframework.factory.BeanFactory proporciona una fábrica de org.springframework.factory.BeanFactory , que al mismo tiempo es un contenedor de aplicaciones IoC. Bean Management se basa en la configuración (java o xml).


La interfaz org.springframework.context.ApplicationContext es un contenedor sobre una fábrica de org.springframework.context.ApplicationContext que proporciona algunas características adicionales, como AOP, transacciones, seguridad, i18n, etc.


¿Qué es un contenedor y cuál es su ciclo de vida?

La base de Spring Framework es un contenedor, y nuestros objetos "viven" en este contenedor.
Un contenedor generalmente crea muchos objetos en función de sus configuraciones y gestiona su ciclo de vida desde la creación de un objeto hasta la destrucción.


Un contenedor es un objeto que implementa la interfaz ApplicationContext .


Ciclo de vida del contenedor
  1. El contenedor se crea cuando se inicia la aplicación.
  2. El contenedor lee los datos de configuración.
  3. La descripción de los contenedores se crea a partir de los datos de configuración
  4. BeanFactoryPostProcessors maneja la descripción del bean
  5. El contenedor crea beans utilizando su descripción.
  6. Los beans se inicializan: los valores de propiedad y las dependencias se incrustan en el bean
  7. Métodos de devolución de llamada de inicio de BeanPostProcessor
  8. La aplicación está funcionando
  9. Cierre de solicitud inicializado
  10. Contenedor cierra
  11. Los métodos de devolución de llamada se llaman

¿Cómo crear una instancia de ApplicationContext?

Spring ofrece varias variaciones de contexto.


Existen varias implementaciones básicas de la interfaz ApplicationContext:


  • FileSystemXmlApplicationContext
  • ClassPathXmlApplicationContext
  • AnnotationConfigApplicationContext
  • XmlWebApplicationContext
  • AnnotationConfigWebApplicationContext

Ejemplos de crear un contexto:


 ApplicationContext ctx = new FileSystemXmlApplicationContext(                                     "c:/bean_properties.xml"); ApplicationContext ctx = new AnnotationConfigApplicationContext(                            "com.springdemoapp.JavaConfig.class"); 

¿Puedes describir el ciclo de vida de un frijol en un contenedor?
  1. Cargando descripciones de bin, creando un gráfico de dependencia (entre beans)
  2. Crear y BeanFactoryPostProcessors
  3. Crear frijoles
  4. Spring inyecta valores y dependencias en las propiedades del bean
  5. Si el bean implementa el método setBeanName() desde la interfaz NameBeanAware, la ID del bean se pasa al método
  6. Si el bean implementa BeanFactoryAware, Spring establece una referencia a la fábrica de setBeanFactory() través de setBeanFactory() desde esta interfaz.
  7. Si el bean implementa la interfaz ApplicationContextAware, Spring establece una referencia al ApplicationContext a través de setApplicationContext() .
  8. BeanPostProcessor es una interfaz especial (sobre esto a continuación), y Spring permite que los contenedores implementen esta interfaz. Al implementar el método postProcessBeforeInitialization() , puede cambiar la instancia del bean antes de inicializarlo (el bean) (establecer propiedades, etc.)
  9. Si se definen los métodos de devolución de llamada, Spring los llama. Por ejemplo, este es un método anotado por @PostConstruct o el método initMethod partir de una anotación @Bean .
  10. El frijol ahora está listo para usar. Se puede obtener utilizando el método ApplicationContext#getBean() .
  11. Después de cerrar el contexto close() método close() de ApplicationContext), el bean se destruye.
  12. Si el bean tiene un método anotado por @PreDestroy , se @PreDestroy este método antes de la destrucción. Si el bean implementa DisposibleBean, Spring llamará al método destroy() para borrar recursos o eliminar procesos en la aplicación. Si el método @Bean se define en la destroyMethod , también se llama.

¿Cómo obtener ApplicationContext en la prueba de integración?

Si está utilizando JUnit 5, debe especificar 2 anotaciones:


  • @ExtendWith (TestClass.class): se usa para indicar una clase de prueba
  • @ContextConfoguration (classes = JavaConfig.class): carga la configuración de java / xml para crear contexto en la prueba

Puede usar la anotación @SpringJUnitConfig , que combina ambas anotaciones.
Puede usar la anotación @SpringJUnitWebConfig para probar la capa web.


¿Cómo cerrar el contexto en una aplicación?

Si esto no es una aplicación web, entonces hay 2 formas:


  • Registre shutdown-hook utilizando la llamada al método registerShutdownHook() , también se implementa en la clase AbstractApplicationContext. Este es el método preferido.
  • Puede llamar al método close() desde la clase AbstractApplicationContext.

En la aplicación Spring Boot:


  • Spring Boot registrará el gancho de apagado por sí mismo.

¿Qué es la configuración de Java? ¿Cómo se aplica?

Para crear una clase con configuración basada en código Java, debe anotarla con
@Configuration .
Esta clase contendrá métodos de fábrica para crear beans en el contenedor.
Estos métodos deben ser anotados con la anotación @Bean .


Un ejemplo:


 @Configuration public class DSConfig {  @Bean  public DataSource dataSource() {      return DataSourceBuilder          .create()          .username("")          .password("")          .url("")          .driverClassName("")          .build();  } } 

Esta clase colocará una instancia de la clase DataSource en el contenedor. Más tarde se puede usar al acceder a la base de datos.


DI utilizando anotaciones, escaneo de clase

Escaneo de componentes: Spring detecta automáticamente los beans que estarán en el contenedor. Estos son contenedores con anotaciones-estereotipos.


Sin embargo, el escaneo de componentes no está habilitado de manera predeterminada.
Para habilitar el escaneo, anote la clase @ Configuración con la anotación @ComponentScanning . Spring escaneará automáticamente el paquete que contiene esta clase y todos sus subpaquetes.
Puede especificar otros paquetes para escanear e incluso clases:


 // 2  @Configuration(basePackages = {"soundsystem", "video"}) 

 //  @Configuration(basePackageClasses = "MyClass.class") 

Cableado automático: Spring inyectará automáticamente dependencias al escanear o colocar un contenedor en un contenedor.
La inyección de dependencia utiliza la anotación @Autowire .


¿Qué son los estereotipos (anotaciones-estereotipos)?

Los estereotipos son anotaciones que denotan una funcionalidad especial.
Todos los estereotipos incluyen la anotación @Component .


ComponenteLa anotación raíz que marca una clase como candidata para la implementación automática
ControladorIndica que la clase es el controlador para enviar datos al frente.
@RestControllerIndica que la clase es el controlador para REST.
Contiene anotaciones de Controller y @ResponseBody
ServicioIndica que la clase es un servicio para ejecutar lógica de negocios.
RepositorioIndica que la clase es un repositorio para trabajar con la base de datos.
@ConfiguraciónIndica que la clase contiene una configuración Java (métodos @ Bean)

¿Cuáles son los ámbitos de la papelera? ¿Cuál es su visibilidad predeterminada?

Alcance - alcance. Hay 2 ámbitos predeterminados.


Singleton
El alcance predeterminado. Solo hay 1 instancia de bean en el contenedor
Prototipo
Cualquier cantidad de instancias bin puede estar en el contenedor

Y 4 ámbitos en una aplicación web.


Solicitud
Alcance: 1 solicitud HTTP. Se crea un nuevo bean para cada solicitud.
Sesión
Alcance - 1 sesión. Se crea un nuevo bean para cada sesión.
Solicitud
Alcance - Ciclo de vida de ServletContext
Zócalo web
Alcance - Ciclo de vida de WebSocket

El alcance se indica utilizando la anotación @Bean métodos @Bean .


¿Cómo se relacionan los diversos ámbitos y subprocesos múltiples?

El alcance del prototipo no es seguro para subprocesos porque no garantiza que se llame a la misma instancia solo en 1 subproceso.


Singleton Scope, por otro lado, es seguro para subprocesos.


¿Cómo se crean los frijoles: instantáneamente o perezosamente? ¿Cómo cambiar este comportamiento?

Los beans Singleton generalmente se crean inmediatamente después del escaneo.
Los beans prototipo generalmente se crean solo a pedido.


Puede usar la anotación @Lazy para indicar cómo inicializar.
Se coloca en los métodos @ Bean, en las clases @ Configuration o en las clases @ Component.
Dependiendo del parámetro (verdadero o falso) que acepte la anotación, la inicialización será lenta o sucederá de inmediato. Por defecto (es decir, sin especificar un parámetro), se usa verdadero.


¿Qué sucede si un contenedor con un ámbito está incrustado en un contenedor con otro ámbito?

El bean Singleton puede integrarse en cualquier otro bean.


Solo el prototype o singleton se puede incrustar en singleton .
Si implementa un prototipo, se creará un prototipo único para cada singleton.


El prototipo puede ser una dependencia para cualquier bean.
Solo puede implementar singleton o prototipo.


¿Qué es un BeanFactoryPostProcessor y cuándo se usa?
  • BeanFactoryPostProcessor funciona en descripciones de bin o metadatos de configuración antes de crear el bin.
  • Spring proporciona varias implementaciones útiles de BeanFactoryPostProcessor , por ejemplo, leer archivos de propiedades y obtener propiedades de BeanFactoryPostProcessor de ellos.
  • Puede escribir su propia implementación de BFPP.

¿Por qué necesitas el método static @ Bean?

Para usar BFPP personalizado. Puede anular el mecanismo para obtener datos de metarchivos.


 @Bean public static PropertySourcesPlaceholderConfigurer pspc() {    //,    pspc } 

Describir las propiedades de la anotación @Bean.
  • destroyMethod : apunta a un método de devolución de llamada. El método está en el contenedor.
  • initMethod : apunta a un método de devolución de llamada. El método está en el contenedor.
  • name : el nombre del frijol. Por defecto, el nombre del bean es el nombre del método.
  • value - alias para nombre ()

¿Qué es un BeanPostProcessor y en qué se diferencia de un BeanFactoryPostProcessor?

Spring utiliza varios BeanPostProcessors.
Por ejemplo, CommonAnnotationPostProcessor o AutowiredAnnotationBeanPostProcessor .
BPP funciona con instancias de bean, es decir el contenedor crea el contenedor y luego comienza BPP.



¿Qué son los métodos de devolución de llamada y cómo usarlos?

Hay 3 opciones para crear tales métodos:


  • @PreDestroy y @PostConstruct
  • Los destroyMethod initMethod y destroyMethod en la anotación destroyMethod que apuntan a métodos en la clase bean
  • InitializingBean#afterPropertiesSet() y DisposableBean#destroy() . Para anular estos métodos, debe implementar las interfaces correspondientes.


¿Cómo puedo usar la anotación @Autowire y cuál es la diferencia entre las formas?

Los siguientes son los tipos de DI que se pueden usar en su aplicación:


  • Constructor DI
  • Setter di
  • Campo di

DI a través del constructor se considera la mejor manera, porque para él no hay necesidad de usar la reflexión, y tampoco tiene las desventajas de DI a través del setter.
No se recomienda DI a través del campo, porque Para esto, se utiliza la reflexión que reduce la productividad.
DI a través del constructor puede conducir a dependencias circulares . Para evitar esto, puede usar la inicialización diferida de beans o DI a través del setter.


Describir el comportamiento de la anotación @Autowired.
  1. El contenedor determina el tipo de objeto a incrustar.
  2. Un contenedor busca beans en un contexto (también conocido como contenedor) que coincida con el tipo deseado
  3. Si hay varios candidatos y uno de ellos está marcado como @Primary , entonces se implementa
  4. Si se @Autowire anotaciones @Autowire + Qualifier , el contenedor utilizará la información de @Qualifier para determinar qué componente implementar
  5. De lo contrario, el contenedor intentará inyectar el componente en función de su nombre o ID.
  6. Si ninguno de los métodos funcionó, se lanzará una excepción

El contenedor maneja la DI utilizando un AutowiredAnnotationBeanPostProcessor . A este respecto, la anotación no se puede utilizar en ningún BeanFactoryPP o BeanPP.


Si el objeto inyectado es una matriz, colección o mapa con un genérico, Spring incorporará todos los beans que son de tipo en esta matriz (u otra estructura de datos). En el caso del mapa, la clave será el nombre del bean.


 // ,   DI @Authowired(required = true/false) 

¿Cómo hacer DI en un campo privado?

Puede usar diferentes tipos de implementación:


  • Constructor
  • Setter
  • Inyección de campo
  • Valor

¿Cómo el uso de @Qualifier complementa a @Autowired?

Spring proporciona la anotación Qualifier para superar el problema de ambigüedad DI.


 @Bean @Qualifier("SomeClass1") public SomeClass getField() {...} //… @Autowire @Qualifier("SomeField1") public SomeClass someField; 

Si el contenedor tiene varios contenedores del mismo tipo (SomeClass), el contenedor implementará exactamente el bean sobre el método @ Bean que tiene el calificador correspondiente. Tampoco puede poner un calificador en un método, sino usar el nombre del bean como parámetro calificador.
El nombre del bean se puede especificar a través del parámetro de anotación Bean y, de manera predeterminada, este es el nombre del método de fábrica.


¿Qué son los objetos proxy y qué tipos de objetos proxy puede crear Spring?

Un proxy es un objeto especial que tiene los mismos métodos públicos que el bean, pero que tiene una funcionalidad adicional.
Dos tipos de proxies:


  • JDK-proxy: proxy dinámico. Las API están integradas en el JDK. Necesita una interfaz
  • Proxy CGLib: no integrado en el JDK. Se usa cuando la interfaz del objeto no está disponible.

Ventajas de los objetos proxy:


  • Permitir agregar extra. lógica - gestión de transacciones, seguridad, registro
  • Separa algún código (registro, etc.) de la lógica principal

¿Cómo se implementa un bean singleton?

Si no hay una instancia de bean en el contenedor, se llama al método @ Bean. Si hay una instancia de bean, se devuelve el bean ya creado.


¿Qué son los perfiles? ¿Cuáles son sus razones para usar?

Al usar la configuración de Java, puede usar la anotación @Profile .
Le permite usar diferentes configuraciones para Spring, dependiendo del perfil especificado.
Se puede colocar en las clases @Configuration y Component , así como en los métodos Bean .


 Profile("!test") //   ,   

 @Bean("dataSource") @Profile("production") public DataSource jndiDataSource() {...} @Bean("dataSource") @Profile("development") public DataSource standaloneDataSource() {...} 

¿Cómo incrustar valores simples en propiedades en Spring?

Puede usar la anotación @Value para @Value .
Dichos valores se pueden obtener de archivos de propiedades, de contenedores, etc.


 @Value("$some.key") public String stringWithDefaultValue; 

Se insertará una cadena en esta variable, por ejemplo, desde la propiedad o desde la vista.


Como de costumbre, envíe correcciones o errores encontrados en PM.

Source: https://habr.com/ru/post/470305/


All Articles