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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2139121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 19:38:45  来源:igfitidea点击:

What is the cleanest way to autowire Spring Beans in a JSP?

javaspringjspautowired

提问by temsa

We're currently adding some new features to an old webapp which was using only JSP without any framework for the front. We have added Spring recently, and we would like to autowire our beans in our modified JSP, while not rewriting everything to use SpringMVC, Struts2 or Tapestry5.

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

We're using autowiring by type, so it leads to get some code like this in the JSP, while previously getting the web application context ( as "wap") :

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

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

We would like not to use such a code but rather automagically inject our beans directly in our JSPs as we would in a business bean using @Autowired annotation.

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

In fact we're looking to the cleanest ways to inject our beans in our JSPs. What do you use ?

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

回答by skaffman

You can use Spring's ContextExposingHttpServletRequest:

您可以使用 Spring 的ContextExposingHttpServletRequest

HttpServletRequest decorator that makes all Spring beans in a given WebApplicationContext accessible as request attributes, through lazy checking once an attribute gets accessed.

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

This would require your controller code to wrap the original HttpServletRequestin a ContextExposingHttpServletRequest, and then forward thatto the JSP. It can either expose specific named beans, or every bean in the context.

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

Of course, this just shifts the problem from your JSPs to your controller code, but that's perhaps a more manageable problem.

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

回答by Bozho

You can't use @Autowireddirectly because both your jsps and servlets are instantiated by the servlet conainer. So they are not part of the spring context and hence their dependencies aren't injected.

您不能@Autowired直接使用,因为您的 jsps 和 servlet 都是由 servlet 容器实例化的。所以它们不是 spring 上下文的一部分,因此它们的依赖项没有被注入。

You can:

你可以:

  1. move all code that to pure servlets, rather than in jsps - leave only presentation in the jsps.
  2. use @Configurableon your servlets (and add a javaagent, as described in the linked docs)
  1. 将所有代码移至纯 servlet,而不是在 jsps 中 - 仅在 jsps 中保留演示文稿。
  2. @Configurable在您的 servlet 上使用(并添加一个 javaagent,如链接文档中所述)

Another way, is to make the servlet part of the current context manually. This is possible in both jsps and servlets:

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

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

    AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();

    bf.autowireBean(this);
}

This will resolve the @Autowiredannotated dependencies.

这将解决带@Autowired注释的依赖关系。

Now, I'm not sure whether servlet containers are required to use only oneinstance of a servlet class. If not, you'd better place the above code in a getter-method for the dependency (getDao()) and if the @Autowiredproperty is null(i.e. another instance of the servlet-class is used by the container) - perform the above operation.

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



That all said, reallyconsider using a web framework (any of the ones you listed). Having logic in jsps is completely wrong, hard to support, hard to read, etc.

话虽如此,请真正考虑使用 Web 框架(您列出的任何框架)。jsps中的逻辑是完全错误的,难以支持,难以阅读等。

回答by Dmytro Plekhotkin

What about overriding jspInit() method and adding Autowiring support:

重写 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); %>

回答by Stephen C

I doubt that there is a clean way to inject dependencies into a JSP.

我怀疑是否有一种干净的方法可以将依赖项注入 JSP。

I think that the clean solution would be to start refactoring your code to get the business logic out of the JSPs, using either SpringMVC or one of the alternatives you cited.

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

Start with one or more minimalist controllers that simply pass the request to the JSPs with the injected beans as attributes; @skaffman's answer gives one way to do that, or you could do it more selectively. Then progressively migrate code out of the JSPs and into the controllers.

从一个或多个极简控制器开始,这些控制器简单地将请求传递给 JSP,并将注入的 bean 作为属性;@skaffman 的回答提供了一种方法,或者您可以更有选择地进行。然后逐步将代码从 JSP 迁移到控制器中。

回答by Scott Carlson

This isn't autowired, but Spring can expose your bean names into the request context, you just need to configure it in the viewResolver.

这不是自动装配的,但是 Spring 可以将您的 bean 名称公开到请求上下文中,您只需要在 viewResolver 中配置它。

From: https://raibledesigns.com/rd/entry/spring_mvc_jstlview_and_exposecontextbeansasattributes

来自: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>