Skip to main content

Quiz: IoC and Spring Fundamentals

Test your knowledge on Inversion of Control and Spring fundamentals.

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


Questions 1-10: Basic Concepts​

Question 1: What does IoC (Inversion of Control) mean?

Answer: IoC (Inversion of Control) is a design principle where the control of object creation and management is transferred from the application code to an external container or framework (like Spring). Instead of the code creating its own dependencies, the container injects them.


Question 2: What is the difference between IoC and DI (Dependency Injection)?

Answer:

  • IoC is the general principle: control is inverted, the framework manages the objects
  • DI is a specific implementation of IoC: dependencies are injected by the container

DI is a way to achieve IoC. IoC can also be achieved through other patterns like the Service Locator.


Question 3: What is the Spring container (ApplicationContext)?

Answer: The ApplicationContext is the IoC container of Spring. It is responsible for:

  • Instantiating beans
  • Configuring beans
  • Assembling dependencies between beans
  • Managing the lifecycle of beans

It is the core of the Spring application that maintains all managed objects.


Question 4: What is a Spring Bean?

Answer: A Spring Bean is an object that is instantiated, assembled, and managed by the Spring IoC container. It is simply a Java object (POJO) whose lifecycle is controlled by Spring rather than the application code.


Question 5: What are the 3 main ways to define a Bean?

Answer:

  1. Stereotype annotations: @Component, @Service, @Repository, @Controller
  2. @Bean in a @Configuration class: method annotated @Bean
  3. XML Configuration: bean (less used today)
// 1. Stereotype annotation
@Service
public class UserService { }

// 2. @Bean
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}

Question 6: Which annotation enables component scanning?

Answer: @ComponentScan enables component scanning. It is automatically included in @SpringBootApplication.

@SpringBootApplication // includes @ComponentScan
public class MyApplication { }

// Or explicitly:
@ComponentScan(basePackages = "com.example")

Question 7: In which package does Spring scan components by default?

Answer: Spring scans by default the package of the class annotated with @SpringBootApplication and all its sub-packages.

If @SpringBootApplication is in com.example.myapp, Spring will scan:

  • com.example.myapp
  • com.example.myapp.service
  • com.example.myapp.controller
  • etc.

Question 8: What is the difference between @Component and @Service?

Answer: Technically, there is no functional difference. Both are stereotypes that mark a class as a Spring Bean.

The difference is semantic:

  • @Component: generic component
  • @Service: business logic
  • @Repository: data access (+ exception translation)
  • @Controller: web MVC controller

It's for code readability and intent.


Question 9: Why use IoC/DI instead of creating objects with new?

Answer: Advantages of IoC/DI:

  1. Loose coupling: classes depend on interfaces, not implementations
  2. Testability: easy to mock dependencies
  3. Flexibility: change implementation without modifying client code
  4. Reusability: independent components
  5. Separation of concerns: business code does not manage object creation

Question 10: What is tight coupling?

Answer: Tight coupling occurs when a class directly depends on a concrete implementation rather than an abstraction.

// Tight coupling (bad)
public class OrderService {
private EmailService emailService = new EmailService(); // new = tight coupling
}

// Loose coupling (good)
public class OrderService {
private final NotificationService notificationService; // interface

public OrderService(NotificationService ns) { // injection
this.notificationService = ns;
}
}

Questions 11-20: Dependency Injection​

Question 11: What are the 3 types of dependency injection?

Answer:

  1. Constructor injection (recommended)
  2. Setter injection (@Autowired on setter)
  3. Field injection (@Autowired on field)
// 1. Constructor (recommended)
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 (avoid)
@Autowired
private UserRepository repo;

Question 12: Why is constructor injection recommended?

Answer: Constructor injection is recommended because:

  1. Immutability: final dependencies, non-modifiable
  2. Mandatory: impossible to create the object without dependencies
  3. Testability: easy to mock in tests
  4. No @Autowired: implicit since Spring 4.3
  5. Cycle detection: compile-time error

Question 13: When is @Autowired optional?

Answer: @Autowired is optional since Spring 4.3 when:

  • The class has only one constructor
  • This constructor takes dependencies as parameters

Spring automatically detects and injects the dependencies.

@Service
public class UserService {
private final UserRepository repo;

// @Autowired optional here (only one constructor)
public UserService(UserRepository repo) {
this.repo = repo;
}
}

Question 14: What happens if Spring finds multiple beans of the same type?

Answer: Spring throws a NoUniqueBeanDefinitionException.

Solutions:

  1. @Primary on the preferred bean
  2. @Qualifier("beanName") to specify which one
  3. Injection by name (parameter name = bean name)
@Primary
@Service
public class EmailNotification implements Notification { }

// or
@Autowired
@Qualifier("smsNotification")
private Notification notification;

Question 15: What is @Primary used for?

Answer: @Primary indicates which bean to use by default when multiple beans of the same type exist.

@Service
@Primary // Will be injected by default
public class EmailNotificationService implements NotificationService { }

@Service
public class SmsNotificationService implements NotificationService { }

The @Primary bean is chosen automatically unless @Qualifier specifies another.


Question 16: What is @Qualifier used for?

Answer: @Qualifier allows specifying exactly which bean to inject when multiple candidates exist.

@Service("emailService")
public class EmailNotification implements Notification { }

@Service("smsService")
public class SmsNotification implements Notification { }

// Usage
@Autowired
@Qualifier("smsService")
private Notification notification;

Question 17: Can you inject a List of all beans of a type?

Answer: Yes! Spring can inject a List containing all beans of type T.

@Service
public class NotificationManager {

private final List services;

public NotificationManager(List services) {
this.services = services; // Contains ALL NotificationService beans
}

public void notifyAll(String message) {
services.forEach(s -> s.send(message));
}
}

Question 18: How to make a dependency optional?

Answer: Several ways:

  1. @Autowired(required = false)
  2. Optional as type
  3. @Nullable annotation
// Option 1
@Autowired(required = false)
private CacheService cacheService;

// Option 2 (recommended)
public MyService(Optional cacheService) {
this.cacheService = cacheService.orElse(null);
}

Question 19: What is a circular dependency?

Answer: A circular dependency occurs when two or more beans depend on each other, forming a cycle.

@Service
public class A {
public A(B b) { } // A depends on B
}

@Service
public class B {
public B(A a) { } // B depends on A -> CYCLE!
}

Spring throws an exception. Solutions: refactor, use @Lazy, or setter injection.


Question 20: How to resolve a circular dependency with @Lazy?

Answer: @Lazy delays injection until the first access, breaking the cycle.

@Service
public class A {
public A(@Lazy B b) { // B will be created later
this.b = b;
}
}

@Service
public class B {
public B(A a) {
this.a = a;
}
}

Note: It's better to refactor to eliminate the cycle!


Questions 21-30: Configuration and Advanced​

Question 21: What is the difference between @Component and @Bean?

Answer:

@Component@Bean
On a classOn a method
Detected by scanIn @Configuration class
Name = class (lowercase)Name = method name
No control over creationFull control over creation
@Component  // Auto-detected
public class MyService { }

@Configuration
public class AppConfig {
@Bean // Manual creation
public ExternalService externalService() {
return new ExternalService("config");
}
}

Question 22: When to use @Bean instead of @Component?

Answer: Use @Bean when:

  1. The class comes from an external library (not modifiable)
  2. Need complex creation logic
  3. Need configuration before creation
  4. Creating third-party objects (RestTemplate, ObjectMapper)
@Bean
public RestTemplate restTemplate() {
RestTemplate rt = new RestTemplate();
rt.setErrorHandler(new CustomErrorHandler());
return rt;
}

Question 23: What is a @Configuration class?

Answer: A @Configuration class is a special class that:

  • Contains @Bean methods
  • Is itself a Spring bean
  • Is processed by CGLIB to ensure bean singleton
  • Replaces XML configuration files
@Configuration
public class AppConfig {

@Bean
public DataSource dataSource() { ... }

@Bean
public JdbcTemplate jdbcTemplate(DataSource ds) {
return new JdbcTemplate(ds); // ds injected
}
}

Question 24: What does @PostConstruct do?

Answer: @PostConstruct marks a method to execute after dependencies are injected, for initialization.

@Service
public class CacheService {

private final DataRepository repo;
private Map cache;

public CacheService(DataRepository repo) {
this.repo = repo;
}

@PostConstruct
public void init() {
// Executed after repo injection
this.cache = repo.loadInitialData();
}
}

Question 25: What does @PreDestroy do?

Answer: @PreDestroy marks a method to execute before the bean is destroyed, for cleanup.

@Service
public class ConnectionPool {

private List connections;

@PreDestroy
public void cleanup() {
// Executed before bean destruction
connections.forEach(Connection::close);
System.out.println("Connections closed");
}
}

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

Answer: The default scope is Singleton: a single instance of the bean is created and shared throughout the Spring context.

Other scopes:

  • prototype: new instance for each injection
  • request: one instance per HTTP request
  • session: one instance per HTTP session
  • application: one instance per ServletContext

Question 27: How to change the scope of a bean?

Answer: With the @Scope annotation:

@Service
@Scope("prototype") // New instance for each injection
public class RequestHandler { }

// Or with the constant
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

// For web scopes
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)

Question 28: What is @Value and what is it used for?

Answer: @Value injects values from property files or default values.

@Service
public class EmailService {

@Value("${app.email.sender}")
private String senderEmail;

@Value("${app.email.enabled:true}") // Default: true
private boolean enabled;

@Value("#{systemProperties['user.name']}") // SpEL
private String systemUser;
}

Question 29: What is @ConfigurationProperties?

Answer: @ConfigurationProperties binds a group of properties to a Java class, cleaner than multiple @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

Question 30: How to test a service with injected dependencies?

Answer: Use mocks with 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");
}
}

Constructor injection makes this possible without Spring.


Score​

Count your correct answers:

ScoreLevel
27-30Excellent - You master Spring IoC
21-26Good - Some minor revisions needed
15-20Average - Review the chapter
Less than 15Needs review - Go over the fundamentals

Back to Chapter 1

Next Chapter