Why am I not allowed in Spring to comment on the last class with @Configuration?

I am studying Core Spring certification, and I have some doubts related to the answer to this question based on the material of the training material.

Why you are not allowed to comment on the last class using @Configuration

My reasoning is as follows to substantiate this statement:

Consider the following configuration class:

@Bean public AccountRepository accountRepository() { return new JdbcAccountRepository(); } @Bean public TransferService transferService() { TransferServiceImpl service = new TransferServiceImpl(); service.setAccountRepository(accountRepository()); return service; } @Bean public AccountService accountService() { return new AccountServiceImpl(accountRepository()); } 

This looks strange at first, because the first method ( accountRepository () ) creates a JdbcAccountRepository object as a bean having id = AccountRepository , which, following Spring's default behavior, is singleton

The second and third methods call twice the number of the accountRepository () method, which should create two instances of JdbcAccountRepository , and this is not so, because it is monophonic !!!

So, to solve this Spring problem, use the Inchitance Proxies strategy, which expects to create a child of my configuration class (the one annotated by @Configuration ), and it does:

  • For each bean, the instance is cached in a child class

  • The child class only calls super at the first instantiation

Thus, the child class is an entry point because this child class implements the following behavior:

open class AppConfig $$ EnhancerByCGLIB $ extends AppConfig {

 public AccountRepository accountRepository() { // if bean is in the applicationContext // return bean // else call super.accountRepository() and store bean in context } public TransferService transferService() { // if bean is in the applicationContext, return bean // else call super.transferService() and store bean in context } ..................................................... ..................................................... ..................................................... } 

Therefore, if I comment on the configuration class with final Spring, it cannot have this behavior, because in Java the final class cannot be a subclass

Is it correct?

Using the same reasoning, can I also argue that in Spring I cannot have a final method annotated using @Bean annotation ?

Since, as shown in the previous example, I have that when a child class (proxy) of my configuration class is created during startup, it happens that for each bean, the instance is cached in the child class , and if it is final, it is impossible (but I am absolutely not sure about this statement)

Am I missing something? Can you give me an accurate explanation?

Tpx

+6
source share
1 answer

Spring creates dynamic proxies for classes annotated with @Configuration classes. Spring uses CGLIB to extend your class to create proxies. Therefore, configuration classes cannot be final.

Regarding accountRepository() , called twice:

If you call the accountRepository() method to create an instance, it is no more than a Spring bean. Spring will have no idea about instances created in this way. Therefore, you will get multiple instances of JdbcAccountRepository

You can save singleton behavior if you configure as shown below:

 @Bean public TransferService transferService(JdbcAccountRepository jdbcAcctRepo) { TransferServiceImpl service = new TransferServiceImpl(); service.setAccountRepository(jdbcAcctRepo); return service; } @Bean public AccountService accountService(JdbcAccountRepository jdbcAcctRepo) { return new AccountServiceImpl(jdbcAcctRepo); } 
+7
source

Source: https://habr.com/ru/post/983855/


All Articles