Spring beans created but not auto-updated

I know that there are a lot of such issues. I looked through a lot of them, but the problem still remains.

I have a service that is created but not supported. No (!) Manual initiation, neither in the project, nor in tests (for example, this question )

Both beans are found and created, says Tomcat. At least the first service is not introduced where it should be. I do not know about the second.

Service (interface):

public interface SchoolService { public School getSchool(String id); } 

Service (implementation):

 @Service @Transactional public class SchoolServiceImpl implements SchoolService { @Autowired private SchoolDAO schoolDAO; public School getSchool(String id) { //database things return school; } } 

Where does he get called

 public class SchoolMenu implements Serializable { @Autowired private SchoolService schoolService; public SchoolMenu () { //here schoolService is null School school = schoolService.getSchool("id"); } } 

context.xml applications

 <?xml version='1.0' encoding='UTF-8' ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <bean id="SchoolServiceImpl" class="content_management.School.service.SchoolServiceImpl"/> <bean id="SchoolDAOImpl" class="content_management.School.dao.SchoolDAOImpl"/> </beans> 

Tomcat Output:

 org.springframework.beans.factory.support.DefaultListableBeanFactory: Pre-instantiating singletons in org.s pringframework.beans.factory.support.DefaultListableBeanFactory@ 57003970: defining beans [SchoolServiceImpl,SchoolDAOImpl]; root of factory hierarchy org.springframework.beans.factory.support.DefaultListableBeanFactory: Creating shared instance of singleton bean 'SchoolServiceImpl' org.springframework.beans.factory.support.DefaultListableBeanFactory: Creating instance of bean 'SchoolServiceImpl' org.springframework.beans.factory.support.DefaultListableBeanFactory: Eagerly caching bean 'SchoolServiceImpl' to allow for resolving potential circular references org.springframework.beans.factory.support.DefaultListableBeanFactory: Finished creating instance of bean 'SchoolServiceImpl' org.springframework.beans.factory.support.DefaultListableBeanFactory: Creating shared instance of singleton bean 'SchoolDAOImpl' org.springframework.beans.factory.support.DefaultListableBeanFactory: Creating instance of bean 'SchoolDAOImpl' org.springframework.beans.factory.support.DefaultListableBeanFactory: Eagerly caching bean 'SchoolDAOImpl' to allow for resolving potential circular references org.springframework.beans.factory.support.DefaultListableBeanFactory: Finished creating instance of bean 'SchoolDAOImpl' 

Where is my mistake?

+5
source share
3 answers

To work @Autowired , SchoolMenu also needs to be Spring bean. If this is not the case, you can get schoolService from the application context. Something like that

 ApplicationContext appContext = new ClassPathXmlApplicationContext("application-context.xml"); SchoolService schoolService = (SchoolService) appContext.getBean(SchoolService.class); 
+2
source

You get access to schoolService in the SchoolMenu constructor:

 public SchoolMenu () { //here schoolService is null School school = schoolService.getSchool("id"); } 

At this point, schoolService has not yet been entered. This cannot be - nothing can happen before the constructor is called.

You can declare a method that will be called after the bean is initialized, annotating it with the javax.annotation.PostConstruct annotation. Perform actions that require nested dependencies in this method, and not in the constructor.

(There are several other ways to achieve the same, for example, implement the InitializingBean interface, but they are a bit outdated)

Example:

 public SchoolMenu () { } @PostConstruct public void init() { // schoolService is NOT null here School school = schoolService.getSchool("id"); } 
+1
source

Instead of defining beans in xml, you can use component checking by adding this configuration to your application context, and Spring automatically scans and detects the bean.

 <context:component-scan base-package="content_management.School" /> 

You also need to add the context namespace so that application-context.xml looks like this:

 <?xml version='1.0' encoding='UTF-8' ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="content_management.School" /> </beans> 
0
source

All Articles