What's Actually Happening

Your Spring Boot application fails to start due to BeanCreationException. The application context cannot initialize beans due to dependency issues or configuration problems.

The Error You'll See

bash
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myService'
defined in file [...]: Instantiation of bean failed; nested exception is 
org.springframework.beans.BeanInstantiationException: Failed to instantiate [...]

Circular dependency:

bash
The dependencies of some of the beans in the application context form a cycle:
   myService defined in file [...]
┌─────┐
|  serviceA defined in file [...]
↑     ↓
|  serviceB defined in file [...]
└─────┘

No unique bean:

bash
No unique bean of type [com.example.MyService] is defined: 
expected single matching bean but found 2: myService1,myService2

Why This Happens

  1. 1.Circular dependency - Beans depend on each other
  2. 2.Missing bean - Required bean not found
  3. 3.Multiple beans - Multiple candidates for injection
  4. 4.Constructor exception - Bean constructor throws exception
  5. 5.Missing configuration - @Configuration missing or wrong
  6. 6.Profile mismatch - Bean not active in current profile
  7. 7.Conditional not met - @ConditionalOnProperty not satisfied
  8. 8.Proxy issues - AOP proxy cannot be created

Step 1: Analyze the Exception

```bash # Check full stack trace: java -jar myapp.jar --debug

# Or enable debug logging: logging.level.org.springframework.beans.factory=DEBUG

# Check which bean failed: # Look for "Error creating bean with name" in logs

# Check nested exceptions: # Follow "nested exception is" chain

# Common error patterns: # 1. NoSuchBeanDefinitionException - Bean missing # 2. NoUniqueBeanDefinitionException - Multiple beans # 3. BeanCurrentlyInCreationException - Circular dependency # 4. UnsatisfiedDependencyException - Dependency missing ```

Step 2: Fix Circular Dependencies

```java // PROBLEM: Circular dependency @Service public class ServiceA { private final ServiceB serviceB;

public ServiceA(ServiceB serviceB) { this.serviceB = serviceB; } }

@Service public class ServiceB { private final ServiceA serviceA;

public ServiceB(ServiceA serviceA) { this.serviceA = serviceA; } }

// SOLUTION 1: Use @Lazy @Service public class ServiceA { private final ServiceB serviceB;

public ServiceA(@Lazy ServiceB serviceB) { this.serviceB = serviceB; } }

// SOLUTION 2: Use setter injection @Service public class ServiceA { private ServiceB serviceB;

@Autowired public void setServiceB(ServiceB serviceB) { this.serviceB = serviceB; } }

// SOLUTION 3: Refactor to remove circular dependency // Create a third service that both depend on @Service public class SharedService { // Common functionality }

@Service public class ServiceA { private final SharedService shared; // No dependency on ServiceB }

// SOLUTION 4: Use ApplicationContext @Service public class ServiceA { @Autowired private ApplicationContext context;

private ServiceB getServiceB() { return context.getBean(ServiceB.class); } } ```

Step 3: Fix Missing Bean Issues

```java // PROBLEM: Bean not found @ComponentScan(basePackages = "com.example") // Missing your package!

@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

// SOLUTION: Add correct package @SpringBootApplication(scanBasePackages = {"com.example", "com.other"}) public class Application { }

// Or add @ComponentScan: @Configuration @ComponentScan({"com.example.services", "com.example.repositories"}) public class AppConfig { }

// PROBLEM: Missing @Component/@Service/@Repository public class MyService { // Missing annotation! }

// SOLUTION: Add annotation @Service public class MyService { }

// PROBLEM: Bean in different module not scanned // SOLUTION: Add to META-INF/spring.factories org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.MyAutoConfiguration

// Or use @Import: @SpringBootApplication @Import({MyConfiguration.class, OtherConfig.class}) public class Application { } ```

Step 4: Fix Multiple Bean Candidates

```java // PROBLEM: Multiple beans of same type @Service("service1") public class MyServiceImpl implements MyService { }

@Service("service2") public class AnotherServiceImpl implements MyService { }

@Controller public class MyController { @Autowired private MyService myService; // Which one? }

// SOLUTION 1: Use @Qualifier @Controller public class MyController { @Autowired @Qualifier("service1") private MyService myService; }

// SOLUTION 2: Use @Primary @Service @Primary public class PrimaryServiceImpl implements MyService { }

// SOLUTION 3: Use name in @Autowired @Controller public class MyController { @Autowired private MyService service1; // Matches bean name }

// SOLUTION 4: Inject all beans @Controller public class MyController { private final Map<String, MyService> services;

public MyController(Map<String, MyService> services) { this.services = services; } }

// SOLUTION 5: Use @Conditional to prevent multiple beans @Service @ConditionalOnProperty(name = "service.impl", havingValue = "primary") public class PrimaryServiceImpl implements MyService { } ```

Step 5: Fix Constructor Exceptions

```java // PROBLEM: Exception in constructor @Service public class MyService { private final Config config;

public MyService(Config config) { if (config == null) { throw new IllegalArgumentException("Config required"); } this.config = config; } }

// SOLUTION: Validate after construction @Service public class MyService { private final Config config;

public MyService(Config config) { this.config = config; }

@PostConstruct public void init() { if (config == null) { throw new IllegalStateException("Config required"); } } }

// Or use @Validated: @Service @Validated public class MyService { private final Config config;

public MyService(@NotNull Config config) { this.config = config; } } ```

Step 6: Fix Profile Issues

```java // PROBLEM: Bean not created due to wrong profile @Service @Profile("production") public class ProductionService { }

// Active profile is "development"

// SOLUTION 1: Set correct profile // application.yml: spring.profiles.active: production

// Or environment variable: SPRING_PROFILES_ACTIVE=production

// Or programmatically: SpringApplication.run(Application.class, "--spring.profiles.active=production");

// SOLUTION 2: Use default profile @Service @Profile({"production", "default"}) public class MyService { }

// SOLUTION 3: Check active profiles Environment env = context.getEnvironment(); String[] profiles = env.getActiveProfiles(); ```

Step 7: Fix Conditional Bean Issues

```java // PROBLEM: Conditional not met @Service @ConditionalOnProperty(name = "feature.enabled", havingValue = "true") public class FeatureService { }

// Property not set or false

// SOLUTION: Set property // application.yml: feature: enabled: true

// Or check why condition failed: @SpringBootApplication @EnableConditionEvaluationReport public class Application { }

// Or debug: logging.level.org.springframework.boot.autoconfigure.condition=DEBUG

// Check report: @Autowired private ConditionEvaluationReport report;

// Common conditionals: @ConditionalOnClass(DataSource.class) @ConditionalOnBean(DataSource.class) @ConditionalOnMissingBean(MyService.class) @ConditionalOnProperty(name = "my.property") @ConditionalOnExpression("${my.property} and ${other.property}") ```

Step 8: Fix AOP Proxy Issues

```java // PROBLEM: Cannot create proxy @Service public class MyService { public final void doSomething() { } // final method!

private void internalMethod() { } // private method! }

@Aspect @Component public class MyAspect { @Around("execution(* com.example.MyService.*(..))") public Object around(ProceedingJoinPoint pjp) { } }

// SOLUTION 1: Remove final/private from proxied methods @Service public class MyService { public void doSomething() { } // Not final

public void internalMethod() { } // Not private }

// SOLUTION 2: Use interface-based proxy public interface MyServiceInterface { void doSomething(); }

@Service public class MyServiceImpl implements MyServiceInterface { @Override public void doSomething() { } }

// Enable proxy: @EnableAspectJAutoProxy(proxyTargetClass = false) @Configuration public class AopConfig { }

// SOLUTION 3: Self-injection for internal calls @Service public class MyService { @Autowired private MyService self;

public void externalMethod() { self.internalMethod(); // Goes through proxy }

@Transactional public void internalMethod() { } } ```

Step 9: Debug Bean Creation

```java // Enable debug logging: logging.level.org.springframework=DEBUG logging.level.org.springframework.beans=TRACE

// Add BeanPostProcessor for debugging: @Component public class BeanCreationLogger implements BeanPostProcessor {

@Override public Object postProcessBeforeInitialization(Object bean, String beanName) { System.out.println("Creating bean: " + beanName + " of type: " + bean.getClass()); return bean; }

@Override public Object postProcessAfterInitialization(Object bean, String beanName) { System.out.println("Bean created: " + beanName); return bean; } }

// List all beans: @SpringBootApplication public class Application implements CommandLineRunner { @Autowired private ApplicationContext context;

public static void main(String[] args) { SpringApplication.run(Application.class, args); }

@Override public void run(String... args) { String[] beans = context.getBeanDefinitionNames(); Arrays.sort(beans); for (String bean : beans) { System.out.println(bean); } } }

// Check bean dependencies: @Autowired private ConfigurableListableBeanFactory beanFactory;

public void printDependencies(String beanName) { String[] dependencies = beanFactory.getDependenciesForBean(beanName); System.out.println("Dependencies of " + beanName + ": " + Arrays.toString(dependencies)); } ```

Step 10: Production Best Practices

```java // 1. Always use constructor injection: @Service public class MyService { private final DependencyA a; private final DependencyB b;

public MyService(DependencyA a, DependencyB b) { this.a = a; this.b = b; } }

// 2. Avoid circular dependencies by design: // Use events instead of direct calls: @Service public class ServiceA { @Autowired private ApplicationEventPublisher eventPublisher;

public void doSomething() { eventPublisher.publishEvent(new MyEvent(this)); } }

@Service public class ServiceB { @EventListener public void handleEvent(MyEvent event) { // React to event } }

// 3. Use proper exception handling: @Service public class MyService { @PostConstruct public void init() { try { // Initialization logic } catch (Exception e) { throw new BeanInitializationException("Failed to initialize", e); } } }

// 4. Profile-specific configurations: @Configuration @Profile("development") public class DevConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder().build(); } }

@Configuration @Profile("production") public class ProdConfig { @Bean public DataSource dataSource() { HikariDataSource ds = new HikariDataSource(); // Production config return ds; } }

// 5. Use Spring Boot Actuator for monitoring: management.endpoints.web.exposure.include=health,info,beans management.endpoint.health.show-details=always ```

Spring Boot Bean Creation Checklist

CheckMethodExpected
Bean annotated@Component/@ServicePresent
Package scanned@ComponentScanIncluded
Dependencies met@AutowiredAll resolved
No circular depsarchitectureNone
Profile correctspring.profiles.activeMatching
Conditions met@ConditionalSatisfied

Verify the Fix

```bash # After fixing:

# 1. Application starts successfully java -jar myapp.jar # Output: Started Application in 5.2 seconds

# 2. Check beans created curl http://localhost:8080/actuator/beans | jq '.contexts[].beans | keys'

# 3. Verify no errors in logs grep -i "BeanCreationException" logs/spring.log # Output: None

# Compare before/after: # Before: BeanCreationException, circular dependency # After: Application starts, all beans created ```

  • [Fix Spring Boot Autowiring Failed](/articles/fix-spring-boot-autowiring-failed)
  • [Fix Spring Boot Application Context Failed](/articles/fix-spring-boot-application-context-failed)
  • [Fix Spring Boot Configuration Not Loading](/articles/fix-spring-boot-configuration-not-loading)