8

我们目前正在向一个仅使用 JSP 且前端没有任何框架的旧 Web 应用程序添加一些新功能。我们最近添加了 Spring,我们希望在修改后的 JSP 中自动装配我们的 bean,而不是重写所有内容以使用 SpringMVC、Struts2 或 Tapestry5。

我们使用按类型自动装配,因此它会导致在 JSP 中获取一些类似这样的代码,而之前获取 Web 应用程序上下文(作为“wap”):

MyDao myDao = (MyDao) wap.getBeansOfType(MyDao.class).values().toArray()[0];

我们不想使用这样的代码,而是像在使用 @Autowired 注解的业务 bean 中那样自动将 bean 直接注入到 JSP 中。

事实上,我们正在寻找将 bean 注入 JSP 的最干净的方法。你用什么 ?

4

5 回答 5

9

您可以使用 Spring 的ContextExposingHttpServletRequest

HttpServletRequest 装饰器,它使给定 WebApplicationContext 中的所有 Spring bean 可以作为请求属性访问,一旦属性被访问,通过延迟检查。

这将需要您的控制器代码将原始代码包装HttpServletRequest在 aContextExposingHttpServletRequest中,然后将其转发JSP。它可以公开特定的命名 bean,也可以公开上下文中的每个 bean。

当然,这只是将问题从您的 JSP 转移到您的控制器代码,但这可能是一个更易于管理的问题。

于 2010-01-26T11:54:38.783 回答
7

您不能@Autowired直接使用,因为您的 jsps 和 servlet 都是由 servlet 容器实例化的。因此它们不是 spring 上下文的一部分,因此它们的依赖项不会被注入。

你可以:

  1. 将所有代码移动到纯 servlet,而不是在 jsps 中 - 只在 jsps 中保留演示文稿。
  2. 在您的 servlet 上使用@Configurable(并添加一个 javaagent,如链接文档中所述)

另一种方法是手动使 servlet 成为当前上下文的一部分。这在 jsps 和 servlet 中都是可能的:

public void init() {
    WebApplicationContext ctx = WebApplicationContextUtils
         .getRequiredWebApplicationContext(getServletContext());

    AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();

    bf.autowireBean(this);
}

这将解决带@Autowired注释的依赖项。

现在,我不确定是否要求 servlet 容器使用一个 servlet 类的实例。如果不是,您最好将上述代码放在依赖项 ( getDao()) 的 getter 方法中,如果@Autowired属性是null(即容器使用 servlet 类的另一个实例) - 执行上述操作。


话虽如此,请真正考虑使用 Web 框架(您列出的任何一个)。在 jsps 中有逻辑是完全错误的,难以支持,难以阅读等。

于 2010-01-26T12:34:21.017 回答
6

覆盖 jspInit() 方法并添加自动装配支持怎么样:

<%@ page import="com.example.ExampleService"%>
<%@ page import="org.springframework.beans.factory.annotation.Value"%>
<%@ page import="org.springframework.beans.factory.annotation.Autowired"%>
<%@ page import="org.springframework.web.context.support.SpringBeanAutowiringSupport"%>
<%!
    public void jspInit() 
    {
        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
        getServletContext());
    }

    @Value("${example.property}")
    private String someField;

    @Autowired
    private ExampleService exampleService;
%>

<% final Object data = exampleService.getSomething(someField); %>
于 2013-04-05T15:23:19.203 回答
4

我怀疑是否有一种干净的方法可以将依赖项注入 JSP。

我认为干净的解决方案是使用 SpringMVC 或您引用的替代方案之一开始重构您的代码以从 JSP 中获取业务逻辑。

从一个或多个极简控制器开始,这些控制器简单地将请求传递给 JSP,并将注入的 bean 作为属性;@skaffman 的回答提供了一种方法来做到这一点,或者你可以更有选择性地做到这一点。然后逐步将代码从 JSP 迁移到控制器中。

于 2010-01-26T12:35:04.300 回答
0

这不是自动装配的,但 Spring 可以将您的 bean 名称公开到请求上下文中,您只需要在 viewResolver 中配置它。

来自:https ://raibledesigns.com/rd/entry/spring_mvc_jstlview_and_exposecontextbeansasattributes

<bean id="viewResolver" 
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="exposeContextBeansAsAttributes" value="true"/>
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
</bean>
于 2019-03-31T02:49:15.610 回答