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

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

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

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

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

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

您可以使用Spring的ContextExposingHttpServletRequest :

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

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

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

您不能直接使用@Autowired ,因为您的jsps和servlet都是由servlet conainer实例化的。 因此它们不属于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类的实例。 如果没有,你最好将上面的代码放在依赖的getter方法中( getDao() ),如果@Autowired属性为null (即容器使用servlet类的另一个实例) – 执行以上操作。


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

如何覆盖jspInit()方法并添加自动assembly支持:

 <%@ 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); %> 

我怀疑是否有一种将dependency injectionJSP的简洁方法。

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

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