Edit Fixed by changing package.
I have this configuration file for spring framework
@Configuration
public class AppConfig {
@Bean(initMethod = "populateCache")
public AccountRepository accountRepository(){
return new JdbcAccountRepository();
}
}
JdbcAccountRepository looks like this.
@Repository
public class JdbcAccountRepository implements AccountRepository {
@Override
public Account findByAccountId(long
return new SavingAccount();
}
public void populateCache() {
System.out.println("Populating Cache");
}
public void clearCache(){
System.out.println("Clearing Cache");
}
}
I'm new to spring framework and trying to use initMethod or destroyMethod. Both of these method are showing following errors.
Caused by: org.springframework.beans.factory.support.BeanDefinitionValidationException: Could not find an init method named 'populateCache' on bean with name 'accountRepository'
Here is my main method.
public class BeanLifeCycleDemo {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = new
AnnotationConfigApplicationContext(AppConfig.class);
AccountRepository bean = applicationContext.getBean(AccountRepository.class);
applicationContext.close();
}
}
Edit I was practicing from a book and had created many packages for different chapters. Error was it was importing different JdbcAccountRepository from different package that did not have that method. I fixed it and it works now. I got hinted at this from answers.
Like you said, if you are mixing configurations types, it can be confusing. Besides, even if you created a Bean of type AccountRepository
, because Spring does a lot of things at runtime, it can call your initMethod, even if the compiler couldn't.
So yes, if you have many beans with the same type, Spring can be confused an know which one to call, hence your exception.
Oh and by the way, having a Configuration
creating the accountRepoisitory
Bean
, you can remove the @Repository
from your JdbcAccountRepository
... It is either @Configuration + @Bean
or @Component/Repository/Service + @ComponentScan
.
TL;DR
Here is more information and how Spring creates your bean : What object are injected by Spring ?
@Bean(initMethod = "populateCache")
public AccountRepository accountRepository(){
return new JdbcAccountRepository();
}
With this code, Spring will :
AccountRepository
named accountRepository
... That's all Spring knows, it won't look inside your method body.accountRepository
of type AccountRepository
.To make sure, try writing this code :
AccountRepository accountRepository = new JdbcAccountRepository();
accountRepository.populateCache(); // Compiler error => the method is not found.
But it works for Spring... Magic.
My recommandation, but you might thinking the same now: If you have classes across many packages to answer different business case, then rely on @Configuration
classes. @ComponentScan
is great to kickstart your development, but reach its limit when your application grows...
Annotate populateCache
method with @PostConstruct
and remove initMethod
from @Bean
. It will work.
You mix two different ways of spring bean declaration:
Using @Configuration
classes. Spring finds all beans annotated with @Configuration
and uses them as a reference to what beans should be created. So if you follow this path of configuration - don't use @Repository
on beans. Spring will detect it anyway
Using @Repository
- other way around - you don't need to use @Configuration
in this case. If you decide to use @Repository
put @PostConstruct
annotation on the method and spring will call it, in this case remove @Configuration
altogether (or at least remove @Bean
method that creates JdbcAccountRepository
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.