【问题标题】:NullPointerException on service spring服务弹簧上的 NullPointerException
【发布时间】:2017-02-16 04:05:59
【问题描述】:

我是 Spring 新手,所以我只是想了解它是如何工作的。我开发了一个简单的 servletproject 使用 spring 来管理 hibernate 框架。

我有服务

@Service("service")
@Transactional
public class CdServiceImpl {

    @Autowired
    private HibernateUtility hibernateutility;

    public int saveCd(CD cd) {
        return hibernateutility.saveCd(cd);
    }

    public List getCd(String searchedCd) {
        return hibernateutility.getCd(searchedCd);
    }

    public List getAllCd() {
        return hibernateutility.getAllCd();
    }

    public void deleteCd(int id) {
        hibernateutility.deleteCd(id);
    }

    public User getUser(String username, String password) {
        return hibernateutility.getUser(username, password);
    }
}

然后我在servlet中使用它

context.scan("it.project");
    context.refresh();
   CdServiceImpl service = (CdServiceImpl) context.getBean("service"); 
    context.register(ApplicationContextConfig.class);
    context.refresh();

1) 它有效,但我有两个问题。这是正确的工作方式吗? 2) 我尝试在 servlet 中设置一个字段,例如:

@Autowired
    private CdServiceImpl service

然后我删除了 context.scan ecc 部分,它给了我 nullpointerexception。为什么?

这样做我还定义了一个新bean

@Bean
    public CdServiceImpl getCdServiceImpl() {
        return new CdServiceImpl();
    }

为什么它不起作用?我知道这可能是一个菜鸟问题,但我想弄清楚弹簧是如何工作的

【问题讨论】:

  • 如果您没有在 xml 文件中明确声明您的 bean,则需要进行上下文扫描,因为使用此组件扫描 Spring 将创建单例 bean,这就是您不需要使用 new 关键字初始化它的原因,但是如果您没有扫描并且你没有在 Spring 文件中提供定义,那么你必须使用 new 关键字来初始化它。
  • (我正在使用注释)在我的配置文件中,我定义了一个 bean!查看我的问题的最后几行
  • 1.不,不是。 2.你的servlet不是由spring管理的,所以它不能注入依赖。
  • 那么正确的方法是什么?我该怎么做才能用 spring 管理 servlet?
  • 你不需要。您可以进行查找,但您进行查找的方式是错误的。使用ContextLoaderListener 加载您的根应用程序上下文,然后在您的servlet 中使用WebApplicationContextUtils init 方法获取ApplicationContext,抓住依赖关系并将其设置为实例字段。你应该像你一样创建和刷新东西。

标签: java spring hibernate servlets


【解决方案1】:

基本上,一旦您开始执行new **ApplicationContext 之类的操作,您就需要挠头,离键盘两步之遥,想想您是否真的想这样做。在 99% 的情况下,这不是您想要或至少不应该做的。

而是让ContextLoaderListener 加载您的配置。假设您没有web.xml,请使用AbstractContextLoaderInitializer 基类。

public ApplicationInitializer extends AbstractContextLoaderInitializer {


    protected WebApplicationContext createApplicationContext() {
        return new AnnotationConfigWebApplicationContext(ApplicationContextConfig.class);
    }

}

注意:这是为了引导您的应用程序,您需要创建上下文。您也可以使用AbstractAnnotationConfigDispatcherServletInitializer,它消除了这种需要,但也创建了一个您不需要的DispatcherServlet

现在您的配置已自动加载,您可以使用WebApplicationContextUtils 获取上下文以进行查找。在 servlet 的 init 方法中执行此操作。

public class YourServlet extends GenericServlet {

    private CdServiceImpl service;

    public void init() throws ServletException {
        ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
        service = ctx.getBean(CdServiceImpl.class);
    }
}

现在您将 bean 初始化一次,不再需要处理任何事情。您也可以使用@Autowired 并手动注入。

public class YourServlet extends GenericServlet {

    @Autowired
    private CdServiceImpl service;

    public void init() throws ServletException {
        ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
        ctx.getAutowireCapableBeanFactory().autowireBean(this);
    }
}

【讨论】:

  • 但是第一类,加载我的配置的那些我必须把它放在哪里?我必须在某处调用“createApplicationContext()”吗? (对不起春天,这对我来说是一个新世界)
  • 不,你不会... servlet 容器会调用它... 假设您使用的是 servlet 3.0 容器并且没有 web.xml 或 servlet 3.0 web.xml。跨度>
猜你喜欢
  • 2020-07-09
  • 1970-01-01
  • 2019-05-17
  • 2018-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多