我们目前正在为一个旧的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的最简洁方法。你用什么?
答案 0 :(得分:9)
您可以使用Spring的ContextExposingHttpServletRequest:
HttpServletRequest装饰器 使所有的Spring bean都在给定 WebApplicationContext可访问为 请求属性,通过懒惰 一旦属性得到检查 访问。
这需要您的控制器代码将原始HttpServletRequest
包装在ContextExposingHttpServletRequest
中,然后将 转发到JSP。它可以公开特定的命名bean,也可以暴露上下文中的每个bean。
当然,这只会将问题从您的JSP转移到您的控制器代码,但这可能是一个更容易管理的问题。
答案 1 :(得分:7)
您不能直接使用@Autowired
,因为您的jsps和servlet都是由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类的另一个实例)由容器使用) - 执行上述操作。
所有人都说,真的考虑使用网络框架(您列出的任何一个)。在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>