在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上下文,因此它们的依赖关系不会被注入。
您可以:
- 将所有代码移动到纯servlet而不是jsps – 只在jsps中保留表示。
- 在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迁移到控制器中。