【问题标题】:@Autowired fails in Spring@Autowired 在 Spring 中失败
【发布时间】:2014-07-23 17:45:36
【问题描述】:

伙计们,
我正在尝试使用 Spring DI 和 MVC (ver 3.2.x) 设置项目。我尝试注入服务实现,但在某些时候失败了。不抛出异常。只是服务对象在预期的地方为空。 下面是代码。

package com.test.domain.web.controller;
.........
@Controller
@RequestMapping(value = "/system/**")
public class InformationController {
@RequestMapping(value = "/classing/{id}", method = RequestMethod.GET)
public ModelAndView getBaleClassing(@PathVariable String id, Model model, HttpServletRequest request) {
    LOG.info("In the system classing...");
    InformationModel informationModel = new InformationModel();
    model.addAttribute("informationModelVO",informationModel.getResult(id));
    return new ModelAndView(SYSTEM_CLASSING_TILE);
}

}


这是业务的模型类。我还尝试在 setter 方法中注释 @Autowired。但没有运气。

package com.test.domain.classing.model;
.........
public class InformationModel  {

@Autowired
InformationService informationService;

public  InformationVO getResult(String id) {
    InformationVO informationVO = null;
    try {
        informationVO = informationService.getInformationById(id); //informationService is null here
    } catch (ServiceException e) {
        LOG.error("Exception: ", e);
    }
    return informationVO;
}

public InformationService getInformationService() {
    return informationService;
}

public void setInformationService(InformationService informationService) {
    this.informationService = informationService;
}
}


这是我的服务实现,唯一符合条件的候选人。我依赖 Spring 来实例化,我不会自己在任何地方实例化服务或 DAO 实现。

package com.test.domain.classing.service;
.......
public class InformationServiceImpl implements InformationService {

    @Autowired
    private InformationDAO informationDAO;

    public InformationServiceImpl() {
        LOG.debug("In the InformationServiceImpl default constructor....");
    }

    public InformationVO getResult(String id) throws ServiceException {
        InformationVO informationVO = informationDAO.getResult(id);
        return informationVO;
    }

    public InformationDAO getInformationDAO() {
        return informationDAO;
    }

    public void setInformationDAO(InformationDAO informationDAO) {
        this.informationDAO = informationDAO;
    }
}

而且,这是 spring 配置(包含服务和 dao)。我不会在 spring 配置中添加 InformationModel,因为我每次都需要新实例。

applicationContext.xml


..........
<context:annotation-config />
<context:component-scan base-package="com.test.domain, com.test.domain.classing.model, com.test.domain.classing.service, com.test.domain.web.controller" />

<bean name="com.test.domain.classing.service.InformationService"  class="com.test.domain.classing.service.InformationServiceImpl">
</bean>

<bean name="com.test.domain.classing.dao.InformationDAO" class="com.test.domain.classing.dao.InformationDAOImpl">
</bean>
..........

mvcContext.xml


<context:component-scan base-package="gov.usda.fsa.pscao.clg.cops.web.controller" />
<!-- Configures the @Controller programming model -->
<mvc:annotation-driven />


从日志中,我可以说 DAO 和服务的实现是实例化的。但是没有任何自动装配发生。即将DAO注入服务或将服务注入模型。 有没有办法在 spring 尝试注入时进行调试(如果是的话,在我的情况下)?

非常感谢任何指针。提前致谢。

【问题讨论】:

  • 您需要注释模型 (@Component) 和服务 (@Service) 类,以便 Spring 管理它们。
  • 非常感谢大家!我将 InformationModel 作为原型范围的 bean,以便每次都创建它。现在它工作正常。

标签: java spring spring-mvc dependency-injection


【解决方案1】:

RPaul 是对的,

试试这个:

@Controller
@RequestMapping(value = "/system/**")
public class InformationController {

@Autowired
InformationModel informationModel;

@RequestMapping(value = "/classing/{id}", method = RequestMethod.GET)
public ModelAndView getBaleClassing(@PathVariable String id, Model model, HttpServletRequest request) {
    LOG.info("In the system classing...");
    model.addAttribute("informationModelVO",informationModel.getResult(id));
    return new ModelAndView(SYSTEM_CLASSING_TILE);
}

}

和,

@Component
public class InformationModel  {
....
} 

还有这个

@Service
public class InformationServiceImpl implements InformationService {
...
}

祝你好运!

【讨论】:

    【解决方案2】:

    Spring @Autowired 注入仅适用于 Spring 托管组件。您的 InformationModel 不是 Spring 托管组件,您尝试使用 new 进行实例化,因此失败。如果您想使用基于注释的配置,那么您可以简单使用 @Service 和 Daos 使用注释服务 @Repository 或 @Component 代替 xml 配置中的 bean 定义。

    【讨论】:

    • 我不同意您避免在配置中混合注释和 XML 的建议。当你的 Spring 配置的那个方面在所有 Spring 上下文中都相同时,注释是最合适的(例如,你总是只有一个给定类型的 bean,所以你用@Autowired 注入它)。 XML 允许您在不同的 Spring 配置之间进行更改(例如,在 JUnit 测试和生产之间,或两个不同的单元测试之间)。我默认使用注解,只有当我发现在不同的 Spring 上下文中需要不同的行为时才将给定的方面移动到 XML。
    • 这是个好主意。可能我在问一个奇怪的问题。是否有可能我可以使用注释来保持代码简短和仅适用于 JUnit 的 xml 配置?就像我可以在 XML 配置中单独保留 DAO 配置,以便在运行 JUnit 时可以切换它
    【解决方案3】:

    没有例外意味着根本没有进行 Autowire 尝试,这反过来意味着您尝试 Autowire 的类不受 Spring 管理。简单的规则是,如果 bean 不是由 Spring 创建的,那么 Spring 的任何东西(包括自动装配)都不会起作用。 如果由于某种原因您每次都需要一个新的 InformationModel 实例,那么您最好不要依赖 Spring,我只需在创建 InformationModel 的构造函数时将所需的参数传递给它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 2015-06-30
      • 1970-01-01
      • 2019-07-31
      • 2012-10-16
      • 2019-01-10
      相关资源
      最近更新 更多