【问题标题】:Spring and ServletContextListenerSpring 和 ServletContextListener
【发布时间】:2016-06-25 17:02:48
【问题描述】:

我在这里阅读了一些关于

的文章和帖子
@Autowired
ServletContext context;

我对@9​​87654324@ 的认识到@Controller。但是我在运行它时遇到了一个很长的异常:

org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'trendsoftCtrl':
Unsatisfied dependency expressed through field 'context':
No qualifying bean of type [javax.servlet.ServletContext] found for dependency [javax.servlet.ServletContext]:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)};
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [javax.servlet.ServletContext] found for dependency [javax.servlet.ServletContext]:
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

这是我的课程。

@WebListener
public class TRSCListner implements ServletContextListener {

@Override
public void contextInitialized(ServletContextEvent event) {
    ServletContext context = event.getServletContext();
    String beanFileName = context.getInitParameter("springBeans");

    GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
    ctx.load(beanFileName);
    ctx.refresh();
    NewsDao newsDao = ctx.getBean("newsDao", NewsDao.class);

    context.setAttribute("appContext", ctx);
    context.setAttribute("dao", newsDao);
}

@Override
public void contextDestroyed(ServletContextEvent event) {
    ServletContext context = event.getServletContext();
    GenericXmlApplicationContext ctx = (GenericXmlApplicationContext) context.getAttribute("appContext");
    ctx.close();
}

}

还有一个

@Controller
public class TrendsoftCtrl {

@Autowired
ServletContext context; 

@RequestMapping ("/welcome")
public ModelAndView helloWorld() {
    NewsDao newsDao = (NewsDao) context.getAttribute("dao");
    List<News> news = newsDao.getAll();

    StringBuilder message = new StringBuilder();

    for (News n : news) {
        message.append(n.getCategory().getName() + "<br>");
        message.append(n.getName() + "<br>");
        message.append(n.getData() + "<br><br>");
    }

    return new ModelAndView("welcome", "news", message.toString());
}

public ServletContext getContext() {
    return context;
}

public void setContext(ServletContext context) {
    this.context = context;
}

}

【问题讨论】:

  • 为什么要在控制器中注入ServletContext?它打破了 Spring 设计时的松散耦合理念。您应该将您的 DAO 类声明为独立 bean,并正确配置您的根上下文和 servlet 上下文。尝试使用 Spring Java 配置,请参阅此链接作为示例:mkyong.com/spring-mvc/… 您无需将任何 bean 放入 ServletContextmanually
  • 好的。但我没有看到任何关于那里的听众的信息
  • 为什么要使用自定义监听器?看起来您只是将一些 bean 放入侦听器的上下文中。您可以完全避免与上下文交互,只需使用 Spring。您可以以声明方式配置这些bean,并使用@Autowired 注释(或@Inject 或``@Resource)将它们注入到您的业务类中。如果您有需要导入的 xml 配置,您可以将其重写为 Java 配置,或者直接导入到 Java 配置中,请参阅此链接:mkyong.com/spring/spring-mixing-xml-and-javaconfig
  • 只有一个问题...为什么? Spring 已经有了ContextLoaderListener,它将加载您的配置。其次,通过上下文传递 bean 是一个坏主意,因为这基本上超出了依赖注入的全部目的。

标签: spring spring-mvc servlets


【解决方案1】:

默认情况下,@Autowired 将执行依赖检查以确保属性已正确连接。当 Spring 找不到要连接的匹配 bean 时,它会抛出异常。要修复它,您可以通过将@Autowired 的“必需”属性设置为 false 来禁用此检查功能。

@Autowired(required=false)

即使 Spring 找不到匹配的 bean,它也会保留 person 属性未设置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-12
    • 2020-11-30
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2012-11-30
    相关资源
    最近更新 更多