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
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:
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:
No unique bean of type [com.example.MyService] is defined:
expected single matching bean but found 2: myService1,myService2Why This Happens
- 1.Circular dependency - Beans depend on each other
- 2.Missing bean - Required bean not found
- 3.Multiple beans - Multiple candidates for injection
- 4.Constructor exception - Bean constructor throws exception
- 5.Missing configuration - @Configuration missing or wrong
- 6.Profile mismatch - Bean not active in current profile
- 7.Conditional not met - @ConditionalOnProperty not satisfied
- 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
| Check | Method | Expected |
|---|---|---|
| Bean annotated | @Component/@Service | Present |
| Package scanned | @ComponentScan | Included |
| Dependencies met | @Autowired | All resolved |
| No circular deps | architecture | None |
| Profile correct | spring.profiles.active | Matching |
| Conditions met | @Conditional | Satisfied |
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 ```
Related Issues
- [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)