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

tem*_*msa 8 java spring jsp autowired

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

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

MyDao myDao = (MyDao) wap.getBeansOfType(MyDao.class).values().toArray()[0];
Run Code Online (Sandbox Code Playgroud)

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

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

ska*_*man 9

您可以使用Spring的ContextExposingHttpServletRequest:

HttpServletRequest装饰器,通过在访问属性后通过延迟检查,使给定WebApplicationContext中的所有Spring bean可作为请求属性访问.

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

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


Boz*_*zho 7

您不能@Autowired直接使用,因为您的jsps和servlet都由servlet conainer实例化.因此它们不是弹簧上下文的一部分,因此它们的依赖性不会被注入.

您可以:

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

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

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

    AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();

    bf.autowireBean(this);
}
Run Code Online (Sandbox Code Playgroud)

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

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


总而言之,真的考虑使用Web框架(您列出的任何一个).在jsps中使用逻辑是完全错误的,难以支持,难以阅读等.


Dmy*_*kin 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); %>
Run Code Online (Sandbox Code Playgroud)