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?- Frequentemente, as informações nelas não são estruturadas, não são coletadas ou não são relevantes
- 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.
- Esses materiais podem ser utilizados na preparação da entrevista, como eles são organizados na forma de perguntas e respostas.
- 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 .

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- O contêiner é criado quando o aplicativo é iniciado.
- O contêiner lê dados de configuração
- A descrição dos compartimentos é criada a partir dos dados de configuração
- BeanFactoryPostProcessors manipula a descrição do bean
- O contêiner cria beans usando sua descrição
- Beans são inicializados - valores e dependências de propriedades são incorporados no bean
- Métodos de retorno de chamada de início BeanPostProcessor
- O aplicativo está em funcionamento
- Fechamento de aplicativo inicializado
- O contêiner fecha
- 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?- Carregando descrições de compartimento, criando um gráfico de dependência (entre beans)
- Criando e
BeanFactoryPostProcessors
- Criar Beans
- Spring injeta valores e dependências nas propriedades do bean
- Se o bean implementar o método
setBeanName()
na interface NameBeanAware, o ID do bean será passado para o método - Se o bean implementar o BeanFactoryAware, o Spring estabelecerá uma referência para a fábrica do bean via
setBeanFactory()
nessa interface. - Se o bean implementar a interface ApplicationContextAware, o Spring estabelecerá uma referência ao ApplicationContext por meio de
setApplicationContext()
. 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.)- 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
. - O feijão está pronto para uso. Pode ser obtido usando o método
ApplicationContext#getBean()
. - Depois que o contexto é fechado (
close()
do ApplicationContext), o bean é destruído. - 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 classeVarredura 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:
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
.
Quais são os escopos da lixeira? Qual é a visibilidade padrão deles?Escopo - escopo. Existem 2 escopos padrão.
E 4 escopos em um aplicativo da web.
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() {
Descreva as propriedades da anotação @BeandestroyMethod
- 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 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- O contêiner determina o tipo de objeto a ser incorporado.
- Um contêiner procura beans em um contexto (também conhecido como contêiner) que corresponde ao tipo desejado
- Se houver vários candidatos, e um deles estiver marcado como
@Primary
, será implementado - Se as anotações do
@Autowire
+ Qualifier
forem usadas, o contêiner usará as informações do @Qualifier
para descobrir qual componente implantar - Caso contrário, o contêiner tentará injetar o componente com base em seu nome ou ID.
- 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.
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() {...}
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.