Preparando-se para a certificação profissional da Spring. Container, IoC, Feijão

Bom dia, Habr.


Hoje decidi apresentar uma tradução de uma série de artigos em preparação para a certificação profissional da Spring .


Esta tradução é apenas o primeiro artigo; se for para o público, continuarei a publicar traduções.


Por que estou fazendo isso, porque já existem vários materiais especializados?
  1. Frequentemente, as informações nelas não são estruturadas, não são coletadas ou não são relevantes
  2. Jovens desenvolvedores podem não saber inglês. Este ciclo pode ser usado não apenas para certificação, mas também para auto-treinamento / repetição de materiais.
  3. Esses materiais podem ser utilizados na preparação da entrevista, como eles são organizados na forma de perguntas e respostas.
  4. Uma vantagem importante e mais importante, esse controle de qualidade é feito de perguntas do Guia Pivotal Oficial de Estudo .

  • Eu deliberadamente perdi algumas perguntas que me pareciam supérfluas ou que não estavam no guia .

Sumário
  1. Injeção de dependência, contêiner, IoC, feijão
  2. AOP (programação orientada a aspectos)
  3. JDBC, Transações, JPA, Dados da Primavera
  4. Bota de mola
  5. Spring mvc
  6. Segurança de primavera
  7. REST
  8. Teste


Vou escrever uma lista de fontes das quais o autor tirou materiais
  • Primavera 5 padrões de design
  • Primavera em Ação 4ª edição
  • Spring Security - Terceira Edição
  • Certificação Core Spring 5 em detalhes por Ivan Krizsan
  • Documentação do Spring e javadocs da API do Spring

Então, vamos começar.


O que é injeção de dependência (DI) e quais são seus benefícios?

A injeção de dependência é um padrão especial que reduz a comunicação entre os componentes do Spring. Assim, ao aplicar o DI, seu código fica mais limpo, mais simples, fica mais fácil de entender e testar.
De acordo com o padrão de DI, a criação de objetos para dependências é transferida para a fábrica ou fornecida a terceiros. Isso significa que podemos nos concentrar no uso desses objetos em vez de criá-los.


Benefícios DI
  • Comunicação reduzida entre partes do aplicativo
  • Teste aprimorado
  • Arquitetura de aplicativos aprimorada
  • Reduz o código padrão
  • Padroniza o desenvolvimento de aplicativos

Por que as interfaces são recomendadas para a criação de Spring beans?
  • Teste aprimorado. Nos testes, o bean pode ser substituído por um objeto especial (mock ou stub) que implementa a interface do bean.
  • Permite usar o mecanismo de proxy dinâmico do JDK (por exemplo, ao criar um repositório via Spring Data)
  • Permite ocultar a implementação

O que é o contexto do aplicativo?

No Spring Framework, a interface org.springframework.factory.BeanFactory fornece uma fábrica de org.springframework.factory.BeanFactory , que ao mesmo tempo é um contêiner de aplicativo de IoC. O gerenciamento de bean é baseado em configuração (java ou xml).


A interface org.springframework.context.ApplicationContext é um invólucro em uma fábrica de beans que fornece alguns recursos adicionais, como AOP, transações, segurança, i18n etc.


O que é um contêiner e qual é o seu ciclo de vida?

A base do Spring Framework é um contêiner e nossos objetos "vivem" nesse contêiner.
Um contêiner normalmente cria muitos objetos com base em suas configurações e gerencia seu ciclo de vida desde a criação de um objeto até a destruição.


Um contêiner é um objeto que implementa a interface ApplicationContext .


Ciclo de vida do contêiner
  1. O contêiner é criado quando o aplicativo é iniciado.
  2. O contêiner lê dados de configuração
  3. A descrição dos compartimentos é criada a partir dos dados de configuração
  4. BeanFactoryPostProcessors manipula a descrição do bean
  5. O contêiner cria beans usando sua descrição
  6. Beans são inicializados - valores e dependências de propriedades são incorporados no bean
  7. Métodos de retorno de chamada de início BeanPostProcessor
  8. O aplicativo está em funcionamento
  9. Fechamento de aplicativo inicializado
  10. O contêiner fecha
  11. Os métodos de retorno de chamada são chamados

Como criar uma instância do ApplicationContext?

A primavera fornece várias variações de contexto.


Existem várias implementações básicas da interface ApplicationContext:


  • FileSystemXmlApplicationContext
  • ClassPathXmlApplicationContext
  • AnnotationConfigApplicationContext
  • XmlWebApplicationContext
  • AnnotationConfigWebApplicationContext

Exemplos de criação de um contexto:


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

Você pode descrever o ciclo de vida de um feijão em um recipiente?
  1. Carregando descrições de compartimento, criando um gráfico de dependência (entre beans)
  2. Criando e BeanFactoryPostProcessors
  3. Criar Beans
  4. Spring injeta valores e dependências nas propriedades do bean
  5. Se o bean implementar o método setBeanName() na interface NameBeanAware, o ID do bean será passado para o método
  6. Se o bean implementar o BeanFactoryAware, o Spring estabelecerá uma referência para a fábrica do bean via setBeanFactory() nessa interface.
  7. Se o bean implementar a interface ApplicationContextAware, o Spring estabelecerá uma referência ao ApplicationContext por meio de setApplicationContext() .
  8. BeanPostProcessor é uma interface especial (sobre isso abaixo), e o Spring permite que os compartimentos implementem essa interface. Ao implementar o método postProcessBeforeInitialization() , você pode alterar a instância do bean antes de inicializá-lo (o bean) (definir propriedades, etc.)
  9. Se os métodos de retorno de chamada estiverem definidos, o Spring os chamará. Por exemplo, este é um método anotado por @PostConstruct ou o método initMethod de uma anotação @Bean .
  10. O feijão está pronto para uso. Pode ser obtido usando o método ApplicationContext#getBean() .
  11. Depois que o contexto é fechado ( close() do ApplicationContext), o bean é destruído.
  12. Se o bean tiver um método anotado por @PreDestroy , esse método será chamado antes da destruição. Se o bean implementar DisposibleBean, o Spring chamará o método destroy() para limpar recursos ou eliminar processos no aplicativo. Se o método @Bean for definido na destroyMethod , também será chamado.

Como obter o ApplicationContext no teste de integração?

Se você estiver usando o JUnit 5, precisará especificar duas anotações:


  • @ExtendWith (TestClass.class) - usado para indicar uma classe de teste
  • @ContextConfoguration (classes = JavaConfig.class) - carrega a configuração java / xml para criar contexto no teste

Você pode usar a anotação @SpringJUnitConfig , que combina essas duas anotações.
Você pode usar a anotação @SpringJUnitWebConfig para testar a camada da web.


Como desligar o contexto em um aplicativo?

Se este não é um aplicativo da web, existem duas maneiras:


  • Registre o shutdown-hook usando a chamada do método registerShutdownHook() , ela também é implementada na classe AbstractApplicationContext. Este é o método preferido.
  • Você pode chamar o método close() da classe AbstractApplicationContext.

No aplicativo Spring Boot:


  • O Spring Boot registrará o gancho de desligamento para você sozinho.

O que é a configuração Java? Como é aplicado?

Para criar uma classe com configuração baseada no código Java, é necessário anotá-la com
@Configuration .
Esta classe conterá métodos de fábrica para criar grãos no contêiner.
Esses métodos devem ser anotados com a anotação @Bean .


Um exemplo:


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

Essa classe colocará uma instância da classe DataSource no contêiner. Posteriormente, pode ser usado ao acessar o banco de dados.


DI usando anotações, varredura de classe

Varredura de componentes - o Spring detecta automaticamente os grãos que estarão no contêiner. Estes são compartimentos com estereótipos de anotações.


No entanto, a verificação de componentes não está ativada por padrão.
Para ativar a varredura, anote a classe @ Configuration com a anotação @ComponentScanning . O Spring verificará automaticamente o pacote que contém essa classe e todos os seus subpacotes.
Você pode especificar outros pacotes para verificação e até classes:


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

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

Fiação automática - O Spring injeta automaticamente dependências ao digitalizar ou colocar uma bandeja em um contêiner.
A injeção de dependência usa a anotação @Autowire .


O que são estereótipos (anotações-estereótipos)?

Estereótipos são anotações que indicam funcionalidade especial.
Todos os estereótipos incluem anotação @Component .


ComponenteA anotação raiz que marca uma classe como candidata à implementação automática
ControladorIndica que a classe é o controlador para enviar dados para a frente.
@RestControllerIndica que a classe é o controlador para o REST.
Contém anotações Controller e @ResponseBody
ServiçoIndica que a classe é um serviço para executar a lógica de negócios.
RepositórioIndica que a classe é um repositório para trabalhar com o banco de dados.
@ConfigurationIndica que a classe contém uma configuração Java (métodos @ Bean)

Quais são os escopos da lixeira? Qual é a visibilidade padrão deles?

Escopo - escopo. Existem 2 escopos padrão.


Singleton
O escopo padrão. Há apenas 1 instância de bean no contêiner
Protótipo
Qualquer número de instâncias de posição pode estar no contêiner

E 4 escopos em um aplicativo da web.


Pedido
Escopo - 1 solicitação HTTP. Um novo bean é criado para cada solicitação.
Sessão
Escopo - 1 sessão. Um novo bean é criado para cada sessão.
Aplicação
Escopo - Ciclo de Vida do ServletContext
Soquete da Web
Escopo - Ciclo de vida do WebSocket

O escopo é indicado usando a anotação @Bean nos métodos @Bean .


Como os vários escopos e multithreading estão relacionados?

O escopo do protótipo não é seguro para threads porque não garante que a mesma instância será chamada apenas em 1 thread.


O Singleton Scope, por outro lado, é seguro para threads.


Como os beans são criados: instantânea ou preguiçosamente? Como mudar esse comportamento?

Os beans Singleton geralmente são criados imediatamente após a varredura.
Os protótipos de feijão geralmente são criados somente mediante solicitação.


Você pode usar a anotação @Lazy para indicar como inicializar.
Ele é colocado nos métodos @ Bean, nas classes @ Configuration ou nas classes @ Component.
Dependendo do parâmetro (verdadeiro ou falso) que a anotação aceita, a inicialização será lenta ou ocorrerá imediatamente. Por padrão (ou seja, sem especificar um parâmetro), true é usado.


O que acontece se um compartimento com um escopo for incorporado em um compartimento com outro escopo?

O feijão Singleton pode ser incorporado em qualquer outro feijão.


Somente prototype ou singleton pode ser incorporado no singleton .
Se você implementar o protótipo, será criado um protótipo exclusivo para cada singleton.


O protótipo pode ser uma dependência para qualquer bean.
Você pode implementar apenas singleton ou protótipo.


O que é um BeanFactoryPostProcessor e quando é usado?
  • BeanFactoryPostProcessor trabalha nas descrições de bin ou metadados de configuração antes que o bin seja criado.
  • O Spring fornece várias implementações úteis do BeanFactoryPostProcessor , por exemplo, lendo arquivos de propriedades e obtendo propriedades de BeanFactoryPostProcessor deles.
  • Você pode escrever sua própria implementação do BFPP.

Por que você precisa do método static @ Bean?

Para usar o BFPP personalizado. Você pode substituir o mecanismo para obter dados de metarquivos.


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

Descreva as propriedades da anotação @Bean
  • destroyMethod - aponta para um método de retorno de chamada. O método está na lixeira.
  • initMethod - aponta para um método de retorno de chamada. O método está na lixeira.
  • name - o nome do bean. Por padrão, o nome do bean é o nome do método.
  • value - alias para name ()

O que é um BeanPostProcessor e como ele é diferente de um BeanFactoryPostProcessor?

O Spring usa vários BeanPostProcessors.
Por exemplo, CommonAnnotationPostProcessor ou AutowiredAnnotationBeanPostProcessor .
O BPP funciona com instâncias de bean, ou seja, o contêiner cria a bandeja e, em seguida, o BPP é iniciado.



O que são métodos de retorno de chamada e como usá-los?

Existem 3 opções para criar esses métodos:


  • @PreDestroy e @PostConstruct
  • Os destroyMethod e destroyMethod na anotação destroyMethod que apontam para métodos na classe de bean
  • InitializingBean#afterPropertiesSet() e DisposableBean#destroy() . Para substituir esses métodos, você precisa implementar as interfaces correspondentes.


Como posso usar a anotação @Autowire e qual a diferença entre as maneiras?

A seguir estão os tipos de DI que podem ser usados ​​no seu aplicativo:


  • Constructor DI
  • Setter di
  • Campo di

A DI através do construtor é considerada a melhor maneira, porque para ele, não há necessidade de usar a reflexão, e ele também não tem as desvantagens da DI através do levantador.
DI através do campo não é recomendado, porque Para isso, é utilizada a reflexão que reduz a produtividade.
A DI através do construtor pode levar a dependências circulares . Para evitar isso, você pode usar a inicialização lenta de beans ou DI através do configurador.


Descreva o comportamento da anotação @Autowired
  1. O contêiner determina o tipo de objeto a ser incorporado.
  2. Um contêiner procura beans em um contexto (também conhecido como contêiner) que corresponde ao tipo desejado
  3. Se houver vários candidatos, e um deles estiver marcado como @Primary , será implementado
  4. Se as anotações do @Autowire + Qualifier forem usadas, o contêiner usará as informações do @Qualifier para descobrir qual componente implantar
  5. Caso contrário, o contêiner tentará injetar o componente com base em seu nome ou ID.
  6. Se nenhum dos métodos funcionou, uma exceção será lançada

O contêiner lida com a DI usando um AutowiredAnnotationBeanPostProcessor . Nesse sentido, a anotação não pode ser usada em nenhum BeanFactoryPP ou BeanPP.


Se o objeto injetado for uma matriz, coleção ou mapa com um genérico, o Spring incorporará todos os beans do tipo nessa matriz (ou outra estrutura de dados). No caso do mapa, a chave será o nome do bean.


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

Como fazer DI em um campo privado?

Você pode usar diferentes tipos de implementação:


  • Construtor
  • Setter
  • Injeção em campo
  • Valor

Como o uso do @Qualifier complementa o @Autowired?

O Spring fornece anotações de Qualificador para superar o problema de ambiguidade de DI.


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

Se houver vários compartimentos do mesmo tipo no contêiner (SomeClass), o contêiner implementará o bean com o qualificador correspondente acima do método @ Bean. Você também não pode colocar um qualificador em um método, mas use o nome do bean como um parâmetro de qualificador.
O nome do bean pode ser especificado através do parâmetro de anotação Bean e, por padrão, este é o nome do método de fábrica.


O que são objetos proxy e que tipos de objetos proxy o Spring pode criar?

Um proxy é um objeto especial que possui os mesmos métodos públicos que o bean, mas que possui funcionalidade adicional.
Dois tipos de proxies:


  • JDK-proxy - proxy dinâmico. APIs são construídas no JDK. Precisa de uma interface
  • Proxy CGLib - não incorporado ao JDK. Usado quando a interface do objeto está indisponível.

Prós de objetos proxy:


  • Permitir adicionar extra. lógica - gerenciamento de transações, segurança, registro
  • Separa algum código (log etc.) da lógica principal

Como um bean singleton é implementado?

Se não houver instância de bean no contêiner, o método @ Bean será chamado. Se houver uma instância de bean, o bean já criado será retornado.


O que são perfis? Quais são os motivos deles para usar?

Ao usar a configuração Java, você pode usar a anotação @Profile .
Ele permite que você use configurações diferentes para o Spring, dependendo do perfil especificado.
Ele pode ser colocado nas classes @Configuration e Component , bem como nos métodos Bean .


 Profile("!test") //   ,   

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

Como incorporar valores simples em propriedades no Spring?

Você pode usar a anotação @Value para @Value .
Esses valores podem ser obtidos em arquivos de propriedades, em compartimentos etc.


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

Uma sequência será incorporada nessa variável, por exemplo, da propriedade ou da visualização.


Como sempre, envie correções ou erros encontrados no PM.

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


All Articles