Quiz: IoC e Fundamentos do Spring
Teste seus conhecimentos sobre Inversão de Controle e os fundamentos do Spring.
30 questões - Clique em cada pergunta para revelar a resposta.
Questões 1-10: Conceitos Básicos
Pergunta 1: O que significa IoC (Inversão de Controle)?
Resposta: IoC (Inversão de Controle) é um princípio de design onde o controle da criação e gerenciamento dos objetos é transferido do código da aplicação para um container ou framework externo (como o Spring). Em vez do código criar suas próprias dependências, é o container que as injeta.
Pergunta 2: Qual a diferença entre IoC e DI (Injeção de Dependência)?
Resposta:
- IoC é o princípio geral: o controle é invertido, o framework gerencia os objetos
- DI é uma implementação específica do IoC: as dependências são injetadas pelo container
DI é uma forma de realizar o IoC. O IoC também pode ser realizado por outros padrões como o Service Locator.
Pergunta 3: O que é o container Spring (ApplicationContext)?
Resposta: O ApplicationContext é o container IoC do Spring. Ele é responsável por:
- Instanciar os beans
- Configurar os beans
- Montar as dependências entre beans
- Gerenciar o ciclo de vida dos beans
É o coração da aplicação Spring que mantém todos os objetos gerenciados.
Pergunta 4: O que é um Bean Spring?
Resposta: Um Bean Spring é um objeto que é instanciado, montado e gerenciado pelo container IoC do Spring. É simplesmente um objeto Java (POJO) cujo ciclo de vida é controlado pelo Spring ao invés do código da aplicação.
Pergunta 5: Quais são as 3 principais formas de definir um Bean?
Resposta:
- Anotações de estereótipo:
@Component,@Service,@Repository,@Controller - @Bean em uma classe @Configuration: método anotado com @Bean
- Configuração XML:
bean(menos usado atualmente)
// 1. Anotação estereótipo
@Service
public class UserService { }
// 2. @Bean
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
Pergunta 6: Qual anotação ativa o scan de componentes?
Resposta: @ComponentScan ativa o scan de componentes. Ela está incluída automaticamente em @SpringBootApplication.
@SpringBootApplication // inclui @ComponentScan
public class MyApplication { }
// Ou explicitamente:
@ComponentScan(basePackages = "com.example")
Pergunta 7: Em qual package o Spring faz o scan de componentes por padrão?
Resposta: O Spring faz o scan por padrão no package da classe anotada com @SpringBootApplication e todos os seus subpackages.
Se @SpringBootApplication está em com.example.myapp, o Spring fará scan em:
com.example.myappcom.example.myapp.servicecom.example.myapp.controller- etc.
Pergunta 8: Qual a diferença entre @Component e @Service?
Resposta: Tecnicamente, não há nenhuma diferença funcional. Ambos são estereótipos que marcam uma classe como Bean do Spring.
A diferença é semântica:
@Component: componente genérico@Service: lógica de negócio@Repository: acesso a dados (+ tradução de exceções)@Controller: controlador web MVC
É para a legibilidade e intenção do código.
Pergunta 9: Por que usar IoC/DI ao invés de criar objetos com new?
Resposta: Vantagens do IoC/DI:
- Baixo acoplamento: classes dependem de interfaces, não de implementações
- Testabilidade: fácil fazer mock das dependências
- Flexibilidade: trocar a implementação sem modificar o código cliente
- Reutilização: componentes independentes
- Separação de responsabilidades: o código de negócio não gerencia a criação de objetos
Pergunta 10: O que é acoplamento forte (tight coupling)?
Resposta: O acoplamento forte ocorre quando uma classe depende diretamente de uma implementação concreta ao invés de uma abstração.
// Acoplamento forte (ruim)
public class OrderService {
private EmailService emailService = new EmailService(); // new = acoplamento forte
}
// Baixo acoplamento (bom)
public class OrderService {
private final NotificationService notificationService; // interface
public OrderService(NotificationService ns) { // injeção
this.notificationService = ns;
}
}
Questões 11-20: Injeção de Dependências
Pergunta 11: Quais são os 3 tipos de injeção de dependências?
Resposta:
- Injeção por construtor (recomendada)
- Injeção por setter (@Autowired no setter)
- Injeção por campo (@Autowired no field)
// 1. Construtor (recomendado)
public class UserService {
private final UserRepository repo;
public UserService(UserRepository repo) { this.repo = repo; }
}
// 2. Setter
@Autowired
public void setRepository(UserRepository repo) { this.repo = repo; }
// 3. Field (evitar)
@Autowired
private UserRepository repo;
Pergunta 12: Por que a injeção por construtor é recomendada?
Resposta: A injeção por construtor é recomendada porque:
- Imutabilidade: dependências
final, não modificáveis - Obrigatória: impossível criar o objeto sem dependências
- Testabilidade: fácil de mockar em testes
- Sem @Autowired: implícito desde o Spring 4.3
- Detecção de ciclos: erro em tempo de compilação
Pergunta 13: Quando @Autowired é opcional?
Resposta: @Autowired é opcional desde o Spring 4.3 quando:
- A classe tem apenas um construtor
- Esse construtor recebe as dependências como parâmetros
O Spring detecta automaticamente e injeta as dependências.
@Service
public class UserService {
private final UserRepository repo;
// @Autowired opcional aqui (apenas um construtor)
public UserService(UserRepository repo) {
this.repo = repo;
}
}
Pergunta 14: O que acontece se o Spring encontrar vários beans do mesmo tipo?
Resposta: O Spring lança uma exceção NoUniqueBeanDefinitionException.
Soluções:
@Primaryno bean preferido@Qualifier("nomeDoBean")para especificar qual- Injeção por nome (nome do parâmetro = nome do bean)
@Primary
@Service
public class EmailNotification implements Notification { }
// ou
@Autowired
@Qualifier("smsNotification")
private Notification notification;
Pergunta 15: Para que serve @Primary?
Resposta: @Primary indica qual bean usar por padrão quando existem vários beans do mesmo tipo.
@Service
@Primary // Será injetado por padrão
public class EmailNotificationService implements NotificationService { }
@Service
public class SmsNotificationService implements NotificationService { }
O bean @Primary é escolhido automaticamente, a menos que @Qualifier especifique outro.
Pergunta 16: Para que serve @Qualifier?
Resposta: @Qualifier permite especificar exatamente qual bean injetar quando existem vários candidatos.
@Service("emailService")
public class EmailNotification implements Notification { }
@Service("smsService")
public class SmsNotification implements Notification { }
// Uso
@Autowired
@Qualifier("smsService")
private Notification notification;
Pergunta 17: É possível injetar uma List com todos os beans de um tipo?
Resposta: Sim! O Spring pode injetar uma List contendo todos os beans do tipo T.
@Service
public class NotificationManager {
private final List services;
public NotificationManager(List services) {
this.services = services; // Contém TODOS os beans NotificationService
}
public void notifyAll(String message) {
services.forEach(s -> s.send(message));
}
}
Pergunta 18: Como tornar uma dependência opcional?
Resposta: Várias formas:
@Autowired(required = false)Optionalcomo tipo- Anotação
@Nullable
// Opção 1
@Autowired(required = false)
private CacheService cacheService;
// Opção 2 (recomendada)
public MyService(Optional cacheService) {
this.cacheService = cacheService.orElse(null);
}
Pergunta 19: O que é uma dependência circular?
Resposta: Uma dependência circular ocorre quando dois ou mais beans dependem um do outro, formando um ciclo.
@Service
public class A {
public A(B b) { } // A depende de B
}
@Service
public class B {
public B(A a) { } // B depende de A -> CICLO!
}
O Spring lança uma exceção. Soluções: refatorar, usar @Lazy ou injeção por setter.
Pergunta 20: Como resolver uma dependência circular com @Lazy?
Resposta: @Lazy adia a injeção até o primeiro acesso, quebrando o ciclo.
@Service
public class A {
public A(@Lazy B b) { // B será criado depois
this.b = b;
}
}
@Service
public class B {
public B(A a) {
this.a = a;
}
}
Nota: O ideal é refatorar para eliminar o ciclo!
Questões 21-30: Configuração e Avançado
Pergunta 21: Qual a diferença entre @Component e @Bean?
Resposta:
| @Component | @Bean |
|---|---|
| Na classe | No método |
| Detectado por scan | Em classe @Configuration |
| Nome = classe (minúsculo) | Nome = nome do método |
| Sem controle sobre criação | Controle total sobre criação |
@Component // Auto-detectado
public class MyService { }
@Configuration
public class AppConfig {
@Bean // Criação manual
public ExternalService externalService() {
return new ExternalService("config");
}
}
Pergunta 22: Quando usar @Bean ao invés de @Component?
Resposta: Use @Bean quando:
- A classe vem de uma biblioteca externa (não modificável)
- Precisa de lógica de criação complexa
- Precisa de configuração antes da criação
- Criação de objetos de terceiros (RestTemplate, ObjectMapper)
@Bean
public RestTemplate restTemplate() {
RestTemplate rt = new RestTemplate();
rt.setErrorHandler(new CustomErrorHandler());
return rt;
}
Pergunta 23: O que é uma classe @Configuration?
Resposta: Uma classe @Configuration é uma classe especial que:
- Contém métodos
@Bean - É ela mesma um bean Spring
- É tratada pelo CGLIB para garantir o singleton dos beans
- Substitui arquivos XML de configuração
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() { ... }
@Bean
public JdbcTemplate jdbcTemplate(DataSource ds) {
return new JdbcTemplate(ds); // ds injetado
}
}
Pergunta 24: O que faz @PostConstruct?
Resposta: @PostConstruct marca um método para ser executado após a injeção das dependências, para inicialização.
@Service
public class CacheService {
private final DataRepository repo;
private Map cache;
public CacheService(DataRepository repo) {
this.repo = repo;
}
@PostConstruct
public void init() {
// Executado após a injeção de repo
this.cache = repo.loadInitialData();
}
}
Pergunta 25: O que faz @PreDestroy?
Resposta: @PreDestroy marca um método para ser executado antes da destruição do bean, para limpeza.
@Service
public class ConnectionPool {
private List connections;
@PreDestroy
public void cleanup() {
// Executado antes da destruição do bean
connections.forEach(Connection::close);
System.out.println("Conexões fechadas");
}
}
Pergunta 26: Qual é o escopo padrão de um bean Spring?
Resposta: O escopo padrão é Singleton: apenas uma instância do bean é criada e compartilhada em todo o contexto Spring.
Outros escopos:
prototype: nova instância a cada injeçãorequest: uma instância por requisição HTTPsession: uma instância por sessão HTTPapplication: uma instância por ServletContext
Pergunta 27: Como mudar o escopo de um bean?
Resposta: Com a anotação @Scope:
@Service
@Scope("prototype") // Nova instância a cada injeção
public class RequestHandler { }
// Ou com a constante
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
// Para web scopes
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
Pergunta 28: O que é @Value e para que serve?
Resposta: @Value injeta valores de arquivos de propriedades ou valores padrão.
@Service
public class EmailService {
@Value("${app.email.sender}")
private String senderEmail;
@Value("${app.email.enabled:true}") // Padrão: true
private boolean enabled;
@Value("#{systemProperties['user.name']}") // SpEL
private String systemUser;
}
Pergunta 29: O que é @ConfigurationProperties?
Resposta: @ConfigurationProperties vincula um grupo de propriedades a uma classe Java, mais limpo do que múltiplos @Value.
@ConfigurationProperties(prefix = "app.email")
public class EmailProperties {
private String sender;
private boolean enabled;
private int maxRetries;
// getters/setters
}
// application.yml
app:
email:
sender: noreply@example.com
enabled: true
max-retries: 3
Pergunta 30: Como testar um serviço com dependências injetadas?
Resposta: Use mocks com Mockito:
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void shouldFindUser() {
// Given
when(userRepository.findById(1L))
.thenReturn(Optional.of(new User(1L, "John")));
// When
User user = userService.findById(1L);
// Then
assertThat(user.getName()).isEqualTo("John");
}
}
A injeção por construtor torna isso possível sem o Spring.
Pontuação
Conte suas respostas corretas:
| Pontuação | Nível |
|---|---|
| 27-30 | Excelente - Você domina IoC no Spring |
| 21-26 | Bom - Pequenas revisões necessárias |
| 15-20 | Médio - Releia o capítulo |
| Menos de 15 | A revisar - Refaça os fundamentos |