Reputation: 3038
I have a Spring Boot application which uses a Redis server for caching. I use Spring RedisTemplate for connecting to the Redis server. I configure the Redis parameters in a @Confiuration
class. However, the redis url and port are stored in DB, and the corresponding DAO is contained as a member in another class (which also contains loads of other global information). I'm trying to autowire the parent class in the Configuration class, but I get an error. This is the code I have:
@Configuration
public class MyConfiguration {
@Autowired
protected GlobalPropertiesLoader globalPropertiesLoader;
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
GlobalPropertiesDAO globalPropertiesDAO = globalPropertiesLoader.getGlobalProperties();
factory.setHostName(globalPropertiesDAO.getRedisUrl());
factory.setPort(globalPropertiesDAO.getRedisPort());
factory.setUsePool(true);
return factory;
}
@Bean
RedisTemplate< String, Object > redisTemplate() {
final RedisTemplate< String, Object > template = new RedisTemplate< String, Object >();
template.setConnectionFactory( jedisConnectionFactory() );
template.setKeySerializer( new StringRedisSerializer() );
template.setHashValueSerializer( new GenericToStringSerializer< Object >( Object.class ) );
template.setValueSerializer( new GenericToStringSerializer< Object >( Object.class ) );
return template;
}
}
GlobalPropertiesLoader is the class which contains the DAO (GlobalPropertiesDAO) as an object. When I try to run my application, I get the following error:
Exception in thread "main"
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.mypkg.CommonsConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected com.utils.GlobalPropertiesLoader com.mypkg.CommonsConfiguration.globalPropertiesLoader; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.utils.GlobalPropertiesLoader] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1202)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1127)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1051)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 50 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected com.utils.GlobalPropertiesLoader com.mypkg.CommonsConfiguration.globalPropertiesLoader; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.utils.GlobalPropertiesLoader] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 61 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.utils.GlobalPropertiesLoader] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1308)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
What is the problem here? Is it not possible to Autowire in @Configuration
class? Because I'm able to autowire the same class in other classes.
::::::::::::::::::::: EDIT ::::::::::::::::::::
I tried @Import
as below:
@Configuration
@Import({GlobalPropertiesLoader.class})
public class CommonsConfiguration {
@Autowired
GlobalPropertiesLoader globalPropertiesLoader;
....
}
However, when I do this, I get the following error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.utils.GlobalPropertiesLoader': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.persistence.repositories.GlobalPropertiesRepository com.utils.GlobalPropertiesLoader.globalPropertiesRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.persistence.repositories.GlobalPropertiesRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1202)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1127)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1051)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 63 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.persistence.repositories.GlobalPropertiesRepository com.utils.GlobalPropertiesLoader.globalPropertiesRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.persistence.repositories.GlobalPropertiesRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 74 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.persistence.repositories.GlobalPropertiesRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1308)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
This is the GlobalPropertiesLoader class:
@Component
@Scope("singleton")
public class GlobalPropertiesLoader {
@Autowired
public GlobalPropertiesRepository globalPropertiesRepository;
private GlobalPropertiesDAO globalProperties;
/*
* Load GlobalProperties once upon loading the context.
*/
@PostConstruct
public void init(){
globalProperties = globalPropertiesRepository.findOne(1L);
....
}
}
And the GlobalPropertiesRepository java:
@Repository
public interface GlobalPropertiesRepository extends CrudRepository<GlobalPropertiesDAO, Long>{
}
Thanks.
Upvotes: 22
Views: 89254
Reputation: 1
@Bean
@Autowired
JedisConnectionFactory jedisConnectionFactory(GlobalPropertiesLoader
globalPropertiesLoader) {
JedisConnectionFactory factory = new JedisConnectionFactory();
GlobalPropertiesDAO globalPropertiesDAO =
globalPropertiesLoader.getGlobalProperties();
factory.setHostName(globalPropertiesDAO.getRedisUrl());
factory.setPort(globalPropertiesDAO.getRedisPort());
factory.setUsePool(true);
return factory;
}
Try it like this
Upvotes: 0
Reputation: 84
I get the same problem before and my initial Class which is "Application.class" is in the package like "abc.klm.prq" and other components' package names are starting with "abc.klm.xyz". So component classes are not in the below hieararchy of "Application.class". When i move the component class to "abc.klm.prq.*" packages the it works.
Upvotes: 0
Reputation: 1764
One of the reason for this error is as you do not have implementation of this class. Create a class called CustomUserDetailsService implementing UserDetailsService and annotate it with @Component. Refer to spring documentation for more. or follow the solution cited by @reos
Upvotes: 1
Reputation: 8324
@Import is to add a configuration class into another configuration class.
http://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch04s03.html
@ComponentScan is to scan for components declared in your code, like @Service, @Component, @Repository, among others.
http://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch06s02.html
I think you need to add in your configuration class the @ComponentScan so it can scan the package with your component classes.
@Configuration
@ComponentScan(value = "org.foo.path.baseFolder")
public class MyConfiguration {
@Autowired
protected GlobalPropertiesLoader globalPropertiesLoader;
Upvotes: 33
Reputation: 14552
@Configuration
s are the classes, which will try to initiate first. Your GlobalPropertiesLoader
doesn't have a instance of it, when MyConfiguration
initiates. Try this.
@Configuration
@Import({GlobalPropertiesLoader.class})
public class MyConfiguration {
}
Upvotes: 2