The UnsatisfiedDependencyException is a common exception that occurs when there is a problem creating a bean in the Spring framework. This exception typically occurs when there is a missing or conflicting dependency between beans in the application context. In this blog post, we will take a look at an example of this exception and show how to resolve it.



Example

Let’s say we have a class, MyService, which depends on another class, MyDependency. In order to use MyService, we need to first create an instance of MyDependency and set it as a property of MyService. We can do this using the @Autowired annotation, which tells Spring to automatically wire the dependency.

@Service
public class MyService {
    @Autowired
    private MyDependency myDependency;

    // other methods and properties
}
@Service
public class MyDependency {
    // other methods and properties
}


Exception

However, if we forget to create an instance of MyDependency in the application context, we will get an UnsatisfiedDependencyException when trying to create an instance of MyService.

Error creating bean with name 'myService': Unsatisfied dependency expressed through field 'myDependency'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.MyDependency' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

The exception message is telling us that there is no bean of type MyDependency available in the application context, and that MyService has a required dependency on it. To resolve this exception, we need to either create an instance of MyDependency or remove the dependency from MyService.

@Service
public class MyService {
    @Autowired(required = false)
    private MyDependency myDependency;

    // other methods and properties
}

or

@Service
public class MyDependency {
    // other methods and properties
}

@Service
public class MyService {
    private MyDependency myDependency;
    @Autowired
    public MyService(MyDependency myDependency){
       this.myDependency = myDependency;
    }
    // other methods and properties
}


Using @ComponentScan annotation

Additionally, to avoid this exception, we can also use the @ComponentScan annotation in the configuration class to scan for the beans in the package where MyDependency class is located.

@Configuration
@ComponentScan(basePackages = {"com.example"})
public class AppConfig {
    // other configuration
}

In this way, Spring will automatically create an instance of MyDependency and wire it to MyService.



Using @Qualifier annotation

One way to resolve the exception is to use the @Qualifier annotation to specify which bean should be used to satisfy the dependency. For example, if we have multiple beans of the same type, we can use the @Qualifier annotation to specify which bean should be used for the dependency.

@Service
@Qualifier("myDependency1")
public class MyDependency1 {
    // other methods and properties
}

@Service
@Qualifier("myDependency2")
public class MyDependency2 {
    // other methods and properties
}

@Service
public class MyService {
    @Autowired
    @Qualifier("myDependency1")
    private MyDependency myDependency;

    // other methods and properties
}


Using @Primary annotation

Another way to resolve the exception is to use the @Primary annotation to specify which bean should be used as the primary bean for a given type. For example, if we have multiple beans of the same type and want to use one of them as the primary bean, we can use the @Primary annotation.

@Service
public class MyDependency1 {
    // other methods and properties
}

@Service
@Primary
public class MyDependency2 {
    // other methods and properties
}

@Service
public class MyService {
    @Autowired
    private MyDependency myDependency;

    // other methods and properties
}

In this example, MyDependency2 will be used as the primary bean for the MyDependency type, and will be autowired to MyService.



Using @Bean annotation

It’s also possible to resolve the exception by creating the missing bean programmatically in the configuration class and register it to the application context using the @Bean annotation

@Configuration
public class AppConfig {
    @Bean
    public MyDependency myDependency() {
        return new MyDependency();
    }
}

In this example, the myDependency bean is created and registered to the application context, and will be available for autowiring to other beans.



Conclusion

In conclusion, UnsatisfiedDependencyException can be resolved in multiple ways, such as removing the dependency, creating the missing bean, using the @Qualifier and @Primary annotations, or programmatically creating and registering the bean in the configuration class. It’s important to understand the root cause of the exception and to choose the appropriate solution accordingly.



Leave a Reply