Java 在JSP中自动连接SpringBean的最干净的方法是什么?

Java 在JSP中自动连接SpringBean的最干净的方法是什么?,java,spring,jsp,autowired,Java,Spring,Jsp,Autowired,我们目前正在向一个旧的webapp添加一些新功能,该webapp只使用JSP,没有任何前端框架。我们最近添加了Spring,我们希望在修改后的JSP中自动连接bean,而不是重写所有内容以使用SpringMVC、Struts2或Tapestry5 我们使用的是按类型自动连接,因此它会导致在JSP中获得一些类似这样的代码,而之前获得的是web应用程序上下文(称为“wap”): 我们不希望使用这样的代码,而是像在使用@Autowired注释的业务bean中一样,自动地将bean直接注入到JSP中 事

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

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

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

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

您可以使用Spring的:

HttpServletRequest修饰符 在给定的时间内制作所有春豆 WebApplicationContext可作为 请求属性,通过lazy 属性获取后进行检查 访问

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


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

您不能直接使用
@Autowired
,因为您的JSP和servlet都是由servlet容器实例化的。因此它们不是spring上下文的一部分,因此它们的依赖关系不会被注入

你可以:

  • 将所有需要的代码移到纯servlet中,而不是JSP中—在JSP中只保留表示
  • 在servlet上使用(并添加javaagent,如链接文档中所述)
  • 另一种方法是手动使servlet成为当前上下文的一部分。这在JSP和servlet中都是可能的:

    public void init() {
        WebApplicationContext ctx = WebApplicationContextUtils
             .getRequiredWebApplicationContext(getServletContext());
    
        AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();
    
        bf.autowireBean(this);
    }
    
    这将解决带注释的依赖项

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



    <>所有人都说,真的考虑使用一个Web框架(你列出的任何一个框架)。在JSP中使用逻辑是完全错误的,难以支持、难以阅读等等。

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

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


    从一个或多个极简控制器开始,这些控制器将请求以注入的bean作为属性传递给JSP@斯卡夫曼的回答给出了一种方法,或者你可以更有选择地去做。然后逐步将代码从JSP迁移到控制器中。

    覆盖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); %>
    

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

    发件人:

    
    
    SpringMVC的好处在于你不必吞下整个药丸。您可以选择要使用的弹簧零件。按照Stephen C的指示执行并开始重构可能会更干净。您认为如何将其更改为JSP之上的过滤器(而不是servlet),JSP从Spring上下文获取所有bean,并将它们放在请求范围内(由预期接口命名),以获得类似的getByType?(+1)请求包装器捕捉得很好。尽管如此,
    @Autowired
    还是不能用那种方式使用?@Bozho:不会,不会,但是bean可以在JSP中引用,没有任何显式的连接。我们可能可以作为过滤器的基础,我肯定知道,但是你不能在5天内重写整个软件(包括拆分前端和业务逻辑),同时添加新功能。事实上,我们应该避免在那里使用DAO,然后只依赖业务对象进行编写,但这只是一些已经编写好的代码,我无法在这么短的时间内重写。说服管理人员将应用程序转换为Spring/Hibernate/Jpa,而不是自制的单机版和公司自制的ORM工具,已经是一个巨大的痛苦。他们只认为这是一种代价。。。
    <%@ 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); %>
    
    <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>