Skip to main content

Quiz: Scopes and Advanced Configuration

Test your knowledge on scopes and configuration properties.

30 questions - Click on each question to reveal the answer.


Questions 1-15: Scopes​

Question 1: What is the default scope of a Spring bean?

Answer: Singleton - a single instance per Spring container.

@Component
public class MyService { } // Default singleton

Question 2: How to create a prototype bean?

Answer:

@Component
@Scope("prototype")
public class PrototypeBean { }

// Or
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyService myService() { }

New instance on each lookup.


Question 3: When to use the prototype scope?

Answer:

  • Objects with mutable state
  • Non-thread-safe objects
  • Expensive objects to create but single-use
  • Independent workflows or processes

Example: file parser, command processor.


Question 4: What is the request scope?

Answer: One instance per HTTP request:

@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestContext {
private User currentUser;
// Request-specific data
}

Destroyed at the end of the request.


Question 5: What is the session scope?

Answer: One instance per HTTP session:

@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ShoppingCart {
private List<Item> items = new ArrayList<>();
}

Persists between requests from the same user.


Question 6: Why is proxyMode necessary for request/session?

Answer: The singleton is created at startup, before any request. The proxy allows access to the scoped bean dynamically:

@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestData { }

@Service // Singleton
public class MyService {
private final RequestData data; // Proxy, not the actual instance
}

Question 7: What are the types of proxyMode?

Answer:

ModeUsage
DEFAULTNo proxy
NONo proxy
INTERFACESJDK proxy (interface)
TARGET_CLASSCGLIB proxy (class)

Use TARGET_CLASS for concrete classes.


Question 8: How to create a custom scope?

Answer:

public class TenantScope implements Scope {

private final ThreadLocal<Map<String, Object>> beans = new ThreadLocal<>();

@Override
public Object get(String name, ObjectFactory<?> factory) {
Map<String, Object> scope = beans.get();
if (!scope.containsKey(name)) {
scope.put(name, factory.getObject());
}
return scope.get(name);
}

@Override
public Object remove(String name) {
return beans.get().remove(name);
}
// ...
}

@Configuration
public class ScopeConfig implements BeanFactoryPostProcessor {

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) {
factory.registerScope("tenant", new TenantScope());
}
}

Question 9: How to manage thread-safety with singletons?

Answer:

  1. Stateless beans (no mutable fields)
  2. Immutable fields (final)
  3. Synchronization if necessary
  4. Use ThreadLocal for per-thread state
@Service
public class StatelessService {
// No mutable fields
private final UserRepository repo; // Immutable

public User process(Long id) {
// Everything in local variables
return repo.findById(id).orElseThrow();
}
}

Question 10: How to check the scope of a bean?

Answer:

@Autowired
private ConfigurableListableBeanFactory beanFactory;

public void checkScope() {
BeanDefinition definition = beanFactory.getBeanDefinition("myBean");
String scope = definition.getScope();
log.info("Scope: {}", scope); // singleton, prototype, etc.
}

Question 11: How to use @RefreshScope?

Answer: For beans that need to be recreated after a configuration refresh:

@RefreshScope
@Component
public class DynamicConfig {

@Value("${app.feature.enabled}")
private boolean featureEnabled;
}

After POST /actuator/refresh, the bean is recreated with new values.


Question 12: How to test scoped beans?

Answer:

@SpringBootTest
@WebAppConfiguration // For request/session scope
class ScopedBeanTest {

@Autowired
private WebApplicationContext context;

@Test
void testRequestScope() {
MockHttpServletRequest request = new MockHttpServletRequest();
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));

try {
RequestData data = context.getBean(RequestData.class);
assertThat(data).isNotNull();
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
}

Question 13: How are prototype beans destroyed?

Answer: Spring does not automatically destroy prototype beans!

@Component
@Scope("prototype")
public class ExpensiveResource implements DisposableBean {

@Override
public void destroy() {
// Never called automatically!
}
}

Must be managed manually or use a BeanFactoryPostProcessor.


Question 14: How to obtain multiple beans of the same type?

Answer:

// List of all beans
@Autowired
private List<NotificationService> notificationServices;

// Map with name as key
@Autowired
private Map<String, NotificationService> notificationMap;

// ObjectProvider for lazy access
@Autowired
private ObjectProvider<NotificationService> provider;

public void notify() {
provider.forEach(service -> service.send(message));
}

Question 15: How to use @Primary vs @Qualifier?

Answer:

// @Primary: default bean
@Service
@Primary
public class EmailNotification implements NotificationService { }

@Service
public class SmsNotification implements NotificationService { }

// @Qualifier: explicit choice
public MyController(@Qualifier("smsNotification") NotificationService notif) { }

Questions 16-30: Configuration​

Question 16: How to read a property with @Value?

Answer:

@Value("${app.name}")
private String appName;

@Value("${app.timeout:5000}") // Default value
private int timeout;

@Value("${app.features}") // List: a,b,c
private List<String> features;

@Value("#{${app.map}}") // Map: {key1: 'val1', key2: 'val2'}
private Map<String, String> map;

Question 17: How to use SpEL in @Value?

Answer:

@Value("#{systemProperties['user.home']}")
private String userHome;

@Value("#{T(java.lang.Math).random()}")
private double randomValue;

@Value("#{myBean.property}")
private String fromBean;

@Value("#{${app.timeout} * 2}")
private int doubleTimeout;

Question 18: How to group properties with @ConfigurationProperties?

Answer:

# application.yml
app:
mail:
host: smtp.example.com
port: 587
username: user
password: secret
@ConfigurationProperties(prefix = "app.mail")
@Validated
public class MailProperties {

@NotBlank
private String host;

@Min(1)
@Max(65535)
private int port;

private String username;
private String password;

// Getters and setters
}

@Configuration
@EnableConfigurationProperties(MailProperties.class)
public class AppConfig { }

Question 19: How to validate properties?

Answer:

@ConfigurationProperties(prefix = "app")
@Validated
public class AppProperties {

@NotNull
private String name;

@Min(1000)
@Max(65535)
private int port;

@Email
private String adminEmail;

@Valid // Validate nested objects
private DatabaseProperties database;
}

The application fails to start if invalid.


Question 20: How to configure nested objects?

Answer:

app:
database:
primary:
url: jdbc:postgresql://primary/db
username: user1
secondary:
url: jdbc:postgresql://secondary/db
username: user2
@ConfigurationProperties(prefix = "app.database")
public class DatabaseProperties {
private DataSourceConfig primary;
private DataSourceConfig secondary;

public static class DataSourceConfig {
private String url;
private String username;
// Getters/setters
}
}

Question 21: How to configure lists?

Answer:

app:
servers:
- host: server1.example.com
port: 8080
- host: server2.example.com
port: 8081
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private List<ServerConfig> servers;

public static class ServerConfig {
private String host;
private int port;
}
}

Question 22: How to use configuration profiles?

Answer:

# application.yml (common)
app:
name: My App

---
# application-dev.yml
spring:
config:
activate:
on-profile: dev
logging:
level:
root: DEBUG

---
# application-prod.yml
spring:
config:
activate:
on-profile: prod
logging:
level:
root: WARN

Activation:

java -jar app.jar --spring.profiles.active=prod

Question 23: How to externalize configuration?

Answer: Priority order (from highest to lowest):

  1. Command line arguments
  2. Environment variables
  3. External application-\{profile\}.yml
  4. External application.yml
  5. application-\{profile\}.yml inside the JAR
  6. application.yml inside the JAR
java -jar app.jar --server.port=9090
export SERVER_PORT=9090

Question 24: How to load configuration from an external file?

Answer:

# External file
java -jar app.jar --spring.config.location=file:/etc/myapp/config/

# Multiple locations
java -jar app.jar --spring.config.location=classpath:/,file:/config/

# Specific file
java -jar app.jar --spring.config.name=custom

Question 25: How to use environment variables?

Answer:

spring:
datasource:
url: ${DB_URL:jdbc:h2:mem:default}
username: ${DB_USER:sa}
password: ${DB_PASSWORD:}

Mapping convention:

  • app.my-property → APP_MY_PROPERTY
  • . → _
  • - → _

Question 26: How to encrypt sensitive properties?

Answer: With Jasypt or Spring Cloud Config:

<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
</dependency>
jasypt:
encryptor:
password: ${JASYPT_PASSWORD}

spring:
datasource:
password: ENC(encrypted_value_here)

Question 27: How to create a custom PropertySource?

Answer:

public class VaultPropertySource extends PropertySource<VaultClient> {

public VaultPropertySource(VaultClient client) {
super("vault", client);
}

@Override
public Object getProperty(String name) {
if (name.startsWith("vault.")) {
return source.getSecret(name.substring(6));
}
return null;
}
}

@Configuration
public class VaultConfig implements EnvironmentPostProcessor {

@Override
public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication app) {
env.getPropertySources().addFirst(new VaultPropertySource(client));
}
}

Question 28: How to refresh configuration on the fly?

Answer:

@RefreshScope
@Component
public class DynamicConfig {

@Value("${app.feature.enabled}")
private boolean enabled;
}
# With Spring Cloud Config
curl -X POST http://localhost:8080/actuator/refresh

@RefreshScope beans are recreated.


Question 29: How to test configuration properties?

Answer:

@SpringBootTest(properties = {
"app.name=Test App",
"app.timeout=1000"
})
class ConfigTest {

@Autowired
private AppProperties properties;

@Test
void propertiesLoaded() {
assertThat(properties.getName()).isEqualTo("Test App");
assertThat(properties.getTimeout()).isEqualTo(1000);
}
}

// Or with test file
@SpringBootTest
@TestPropertySource("classpath:test-config.properties")
class ConfigTest { }

Question 30: What are the best practices for configuration?

Answer:

  1. Type with @ConfigurationProperties
  2. Validate with @Validated
  3. Externalize secrets
  4. Document each property
  5. Sensible default values
  6. Profiles for environments
  7. Do not commit secrets
  8. Centralize with Config Server in microservices
@ConfigurationProperties(prefix = "app")
@Validated
public class AppProperties {

/**
* Application name displayed in logs.
*/
@NotBlank
private String name = "My Application";
}

Score​

ScoreLevel
27-30Excellent - Mastered scopes and configuration
21-26Good - Some revisions needed
15-20Average - Review the chapter
Less than 15Needs improvement

Back to Module 5