Quiz: Beans e Contexto Spring
Teste seus conhecimentos sobre beans e o contexto de aplicação.
30 perguntas - Clique em cada pergunta para revelar a resposta.
Perguntas 1-15: Beans
Pergunta 1: O que é um bean Spring?
Resposta: Um bean é um objeto gerenciado pelo container Spring IoC:
- Criado e configurado pelo Spring
- Injeção automática de dependências
- Ciclo de vida gerenciado
- Singleton por padrão
Pergunta 2: Como declarar um bean com uma anotação?
Resposta:
// Com estereótipo (scan automático)
@Component
public class MyService { }
@Service
public class UserService { }
@Repository
public class UserRepository { }
@Controller
public class UserController { }
Pergunta 3: Como declarar um bean com @Bean?
Resposta:
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper()
.registerModule(new JavaTimeModule());
}
}
Pergunta 4: Qual a diferença entre @Component e @Bean?
Resposta:
| @Component | @Bean |
|---|---|
| Em uma classe | Em um método |
| Detectado automaticamente por scan | Declarado explicitamente |
| Classes que você controla | Classes de terceiros |
| Configuração limitada | Controle total |
Pergunta 5: Qual é o nome padrão de um bean?
Resposta: O nome da classe em camelCase:
@Component
public class UserService { }
// Nome: userService
@Bean
public RestTemplate myRestTemplate() { }
// Nome: myRestTemplate
Personalizar:
@Component("customName")
@Bean("customName")
Pergunta 6: Como recuperar um bean pelo nome?
Resposta:
@Autowired
private ApplicationContext context;
public void example() {
UserService service = context.getBean("userService", UserService.class);
// Ou por tipo
UserService service = context.getBean(UserService.class);
}
Pergunta 7: O que é o ciclo de vida de um bean?
Resposta:
- Instanciação: criação do objeto
- Injeção: injeção das dependências
- Inicialização: métodos @PostConstruct
- Uso: bean pronto
- Destruição: métodos @PreDestroy
Pergunta 8: Como executar código após a inicialização?
Resposta:
@Component
public class DataLoader {
@PostConstruct
public void init() {
log.info("Bean inicializado");
loadData();
}
}
// Ou com @Bean
@Bean(initMethod = "init")
public MyService myService() { }
Pergunta 9: Como executar código antes da destruição?
Resposta:
@Component
public class ResourceManager {
@PreDestroy
public void cleanup() {
log.info("Limpando recursos");
closeConnections();
}
}
// Ou com @Bean
@Bean(destroyMethod = "close")
public DataSource dataSource() { }
Pergunta 10: O que são InitializingBean e DisposableBean?
Resposta: Interfaces alternativas para o ciclo de vida:
@Component
public class MyBean implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() {
// Após injeção
}
@Override
public void destroy() {
// Antes da destruição
}
}
Prefira @PostConstruct/@PreDestroy para menor acoplamento.
Pergunta 11: Como implementar ApplicationRunner?
Resposta:
@Component
public class StartupRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
log.info("Aplicação iniciada");
// Argumentos: args.getOptionValues("config")
}
}
Executado após o contexto estar totalmente iniciado.
Pergunta 12: Como implementar CommandLineRunner?
Resposta:
@Component
public class DataInitializer implements CommandLineRunner {
private final UserRepository repository;
@Override
public void run(String... args) {
repository.save(new User("Admin"));
log.info("Dados inicializados");
}
}
Pergunta 13: Como ordenar a execução dos runners?
Resposta:
@Component
@Order(1)
public class FirstRunner implements CommandLineRunner { }
@Component
@Order(2)
public class SecondRunner implements CommandLineRunner { }
Pergunta 14: Como criar um bean condicional?
Resposta:
@Bean
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
public CacheManager cacheManager() { }
@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSource defaultDataSource() { }
@Bean
@Profile("dev")
public DevService devService() { }
Pergunta 15: O que é @Lazy?
Resposta: Adia a criação do bean até o primeiro acesso:
@Component
@Lazy
public class HeavyService {
public HeavyService() {
// Chamado somente no primeiro acesso
}
}
// Ou na injeção
public MyController(@Lazy HeavyService service) { }
Perguntas 16-30: Contexto e Escopos
Pergunta 16: O que é o ApplicationContext?
Resposta: O container central do Spring que:
- Gerencia todos os beans
- Fornece injeção de dependências
- Publica eventos
- Carrega recursos
- Gerencia internacionalização
Pergunta 17: Quais são os escopos de beans disponíveis?
Resposta:
| Escopo | Descrição |
|---|---|
singleton | Uma instância por contexto (padrão) |
prototype | Nova instância a cada requisição |
request | Uma instância por requisição HTTP |
session | Uma instância por sessão HTTP |
application | Uma instância por ServletContext |
Pergunta 18: Como definir o escopo de um bean?
Resposta:
@Component
@Scope("prototype")
public class PrototypeBean { }
@Bean
@Scope("request")
public RequestContext requestContext() { }
// Ou com constantes
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Pergunta 19: Qual problema ocorre ao injetar um prototype em um singleton?
Resposta: O singleton sempre mantém a mesma instância do prototype:
@Component // Singleton
public class SingletonService {
private final PrototypeBean proto; // Sempre a mesma instância!
public SingletonService(PrototypeBean proto) {
this.proto = proto;
}
}
Solução: usar ObjectProvider ou @Lookup.
Pergunta 20: Como usar ObjectProvider?
Resposta:
@Component
public class SingletonService {
private final ObjectProvider<PrototypeBean> protoProvider;
public void doWork() {
PrototypeBean proto = protoProvider.getObject(); // Nova instância
}
}
Pergunta 21: Como usar @Lookup?
Resposta:
@Component
public abstract class SingletonService {
@Lookup
protected abstract PrototypeBean getPrototype();
public void doWork() {
PrototypeBean proto = getPrototype(); // Nova instância
}
}
Pergunta 22: Como escutar eventos do contexto?
Resposta:
@Component
public class ContextListener {
@EventListener
public void onContextRefreshed(ContextRefreshedEvent event) {
log.info("Contexto atualizado");
}
@EventListener
public void onContextClosed(ContextClosedEvent event) {
log.info("Contexto fechado");
}
}
Pergunta 23: Como publicar um evento personalizado?
Resposta:
// Evento
public class UserCreatedEvent extends ApplicationEvent {
private final User user;
public UserCreatedEvent(Object source, User user) {
super(source);
this.user = user;
}
}
// Publicação
@Service
public class UserService {
private final ApplicationEventPublisher publisher;
public void createUser(User user) {
userRepository.save(user);
publisher.publishEvent(new UserCreatedEvent(this, user));
}
}
// Escuta
@Component
public class UserEventListener {
@EventListener
public void onUserCreated(UserCreatedEvent event) {
log.info("Usuário criado: {}", event.getUser().getName());
}
}
Pergunta 24: Como escutar um evento de forma assíncrona?
Resposta:
@EnableAsync
@Configuration
public class AsyncConfig { }
@Component
public class AsyncListener {
@Async
@EventListener
public void onEvent(MyEvent event) {
// Executado em outra thread
}
}
Pergunta 25: Como acessar o ambiente Spring?
Resposta:
@Component
public class ConfigService {
private final Environment env;
public ConfigService(Environment env) {
this.env = env;
}
public void showConfig() {
String property = env.getProperty("app.name");
String[] profiles = env.getActiveProfiles();
boolean isDev = env.acceptsProfiles(Profiles.of("dev"));
}
}
Pergunta 26: Como carregar recursos externos?
Resposta:
@Component
public class ResourceLoader {
@Value("classpath:data/config.json")
private Resource configResource;
public void load() throws IOException {
String content = new String(configResource.getInputStream().readAllBytes());
}
}
Pergunta 27: Como implementar EnvironmentPostProcessor?
Resposta:
public class CustomEnvProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication app) {
// Modificar o ambiente antes da inicialização
Map<String, Object> props = new HashMap<>();
props.put("custom.property", "value");
env.getPropertySources().addFirst(new MapPropertySource("custom", props));
}
}
Registrar em META-INF/spring.factories.
Pergunta 28: Como usar perfis Spring?
Resposta:
// Bean ativo somente em dev
@Component
@Profile("dev")
public class DevOnlyService { }
// Bean ativo exceto em prod
@Component
@Profile("!prod")
public class NonProdService { }
// Vários perfis
@Component
@Profile({"dev", "test"})
public class DevTestService { }
Pergunta 29: Como definir beans em configurações separadas?
Resposta:
@Configuration
public class DatabaseConfig {
@Bean
public DataSource dataSource() { }
}
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain() { }
}
@Configuration
@Import({DatabaseConfig.class, SecurityConfig.class})
public class AppConfig { }
Pergunta 30: Como testar um contexto Spring?
Resposta:
@SpringBootTest
class ContextTest {
@Autowired
private ApplicationContext context;
@Test
void contextLoads() {
assertThat(context).isNotNull();
assertThat(context.getBean(UserService.class)).isNotNull();
}
@Test
void beanExists() {
assertThat(context.containsBean("userService")).isTrue();
}
}
Pontuação
| Pontuação | Nível |
|---|---|
| 27-30 | Excelente - Beans e contexto dominados |
| 21-26 | Bom - Algumas revisões |
| 15-20 | Médio - Releia o capítulo |
| Menos de 15 | Precisa revisar |