Spring bean已创建但未自动装配

时间:2015-04-22 13:31:16

标签: java spring dependency-injection

我知道有很多类似的问题。我看了很多,但问题仍然存在。

我有一个已创建但未自动装配的服务。在项目和测试中都没有(!)手动启动(如this question

Tomcat输出说,

找到并创建了这两个bean。至少第一项服务不会注入应有的位置。我不知道第二个。

服务(接口):

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

服务(实施):

@Service
@Transactional
public class SchoolServiceImpl implements SchoolService {

  @Autowired
  private SchoolDAO schoolDAO;

  public School getSchool(String id) {
    //database things
    return school;
  }

}

“被叫”的地方

public class SchoolMenu implements Serializable {

  @Autowired
  private SchoolService schoolService;

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

}

应用context.xml中

<?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输出:

org.springframework.beans.factory.support.DefaultListableBeanFactory: Pre-instantiating singletons in org.springframework.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'

我的错误在哪里?

3 个答案:

答案 0 :(得分:2)

为了让@Autowired起作用,SchoolMenu也必须是一个Spring bean。如果不是,您可以从应用程序上下文中获取schoolService。像这样的东西

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

答案 1 :(得分:1)

您正在schoolService的构造函数中访问SchoolMenu

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

此时,schoolService尚未注入。它不可能 - 在构造函数被调用之前,没有任何事情可以发生。

通过使用javax.annotation.PostConstruct注释对bean进行注释,可以在初始化bean之后声明要调用的方法。执行需要在该方法中注入依赖项的操作,而不是在构造函数中。

(还有其他一些方法可以实现相同的功能,例如实现InitializingBean接口,但这些方法有点过时了)

示例:

public SchoolMenu () {
}

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

答案 2 :(得分:0)

您可以通过将此配置添加到应用程序上下文而不是在xml中定义bean,而Spring将自动扫描并检测bean。

<?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>

此外,您需要添加上下文命名空间,以便application-context.xml如下所示:

{{1}}