在JSP中自动装配Spring Beans的最简洁方法是什么?

时间:2010-01-26 11:48:25

标签: java spring jsp autowired

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

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

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

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

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

5 个答案:

答案 0 :(得分:9)

您可以使用Spring的ContextExposingHttpServletRequest

  

HttpServletRequest装饰器   使所有的Spring bean都在给定   WebApplicationContext可访问为   请求属性,通过懒惰   一旦属性得到检查   访问。

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

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

答案 1 :(得分:7)

您不能直接使用@Autowired,因为您的jsps和servlet都是由servlet变量实例化的。因此它们不属于弹簧上下文,因此它们的依赖性不会被注入。

你可以:

  1. 将所有代码移动到纯servlet,而不是jsps中 - 只在jsps中保留显示。
  2. 在您的servlet上使用@Configurable(并添加一个javaagent,如链接文档中所述)
  3. 另一种方法是手动使servlet成为当前上下文的一部分。这在jsps和servlet中都是可能的:

    public void init() {
        WebApplicationContext ctx = WebApplicationContextUtils
             .getRequiredWebApplicationContext(getServletContext());
    
        AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();
    
        bf.autowireBean(this);
    }
    

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

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


    所有人都说,真的考虑使用网络框架(您列出的任何一个)。在jsps中使用逻辑是完全错误的,难以支持,难以阅读等等。

答案 2 :(得分:5)

如何覆盖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); %>

答案 3 :(得分:4)

我怀疑是否有一种将依赖注入JSP的简洁方法。

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

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

答案 4 :(得分: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>