Pular para o conteúdo principal

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 classeEm um método
Detectado automaticamente por scanDeclarado explicitamente
Classes que você controlaClasses de terceiros
Configuração limitadaControle 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:

  1. Instanciação: criação do objeto
  2. Injeção: injeção das dependências
  3. Inicialização: métodos @PostConstruct
  4. Uso: bean pronto
  5. 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:

EscopoDescrição
singletonUma instância por contexto (padrão)
prototypeNova instância a cada requisição
requestUma instância por requisição HTTP
sessionUma instância por sessão HTTP
applicationUma 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çãoNível
27-30Excelente - Beans e contexto dominados
21-26Bom - Algumas revisões
15-20Médio - Releia o capítulo
Menos de 15Precisa revisar

Voltar ao Módulo 5