我们可以在jsp中使用@autowired吗?如果是,那么如何。?

Posted

技术标签:

【中文标题】我们可以在jsp中使用@autowired吗?如果是,那么如何。?【英文标题】:Can we use @autowired in jsp. If yes then how.? 【发布时间】:2013-12-29 09:10:43 【问题描述】:

我正在使用 spring 和 hibernate 构建一个 Web 应用程序。 我想为此构建服务器端表,我需要一个用 Service 类编写的方法。但要成功执行它,我需要将它自动连接到相应的类,因为现在它正在给一个空指针异常访问表。

【问题讨论】:

在您的问题中,您在哪里询问有关 JSP 或 Spring MVC 的问题?请提供更多详细信息。 即使您会这样做,这仍然是一种不好的做法。正确的方法是在控制器中完成所有工作并通过模型将结果传递给视图。 【参考方案1】:

没有。您不能在 JSP 中自动装配 bean。 Beans 自动装配在自己注释的类中。任何用@Component@Component 的子类注解的类都可以注解其他bean。

【讨论】:

【参考方案2】:

不,您不能在 JSP 中使用 @autowired。如果您需要 JSP 中的 bean,您可以使用以下内容:

ApplicationContext ac = RequestContextUtils.getWebApplicationContext(request);
ac.getBean("yourBeanName");

编辑为:-

示例 Bean:

@Component("abcBean")
public Abc

    public void sysout()
        System.out.printn("Hello world");
    


在 JSP 中:

您可以将此 spring 托管单例 bean 用作:

ApplicationContext ac = RequestContextUtils.getWebApplicationContext(request);
Abc abc = (Abc) ac.getBean("abcBean");
abc.sysout();

如有其他需要请留言。

【讨论】:

感谢您的帮助。但如果你能帮我举个例子,或者一个例子的链接,那就太好了。 嗨 HVT7,你的问题解决了吗? 哦是的...!!感谢您的帮助..! getWebApplicationContext 已弃用。您可以改用findWebApplicationContext 这样就可以了【参考方案3】:

如果您使用 Spring MVC,您可以通过 ModelAndView 将您的服务传递给 JSP。

假设你有:控制器

@Controller
public void MyController 

    @Autowired
    private MyServiceInterface myService;

    @RequestMapping(value="myUrl")
    public ModelAndView displayPage() 
       //do some stuff
        return new ModelAndView("myView").addObject("myService", myService);
    

JSP:

<html>
.
$myService.myMethodIWantToUse
.
</html>

但正如 Slava Semushin 所说,这是一种不好的做法。如果您从您的方法中排除结果并将它们打印在您的 JSP 中,请将它们放入您的模型 (ModelAndView)

【讨论】:

在 request/mav.addObject 中传递 bean 不是理想的方式...应该始终从 ApplicationContext 获取 bean【参考方案4】:

这不是在 MVC 应用程序中执行的理想方式,如果您需要从服务中获取某些内容,您应该对控制器进行 HTTP 调用。

无法在 JSP 中自动装配 Bean。您必须使用 RequestContextUtils 类来获取 spring 容器中定义的 bean。

【讨论】:

【参考方案5】:

如果您使用的是 Tomcat,可以,但这需要一些工作。

解决方案是包装普通的 tomcat 实例管理器(它用于实例化 JSP 实例),然后通过侦听器注入包装后的版本。

首先,包装管理器类。它非常简单,只需在返回新创建的对象之前将 bean 注入它们。

public class SpringInstanceManager implements InstanceManager 

    ServletContext ctx;
    InstanceManager manager;

    public SpringInstanceManager(ServletContext ctx, InstanceManager manager)
        this.ctx = ctx;
        this.manager = manager;           
    

    public Object processAnnotations(Object o) throws IllegalAccessException, InvocationTargetException, NamingException 
        if (o != null && o.getClass().getName().endsWith("_jsp"))             
            SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(o, ctx);
        
        return o;
    

    @Override
    public Object newInstance(Class<?> clazz) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException 
        return processAnnotations(manager.newInstance(clazz));
    

    @Override
    public Object newInstance(String className) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException 
        return processAnnotations(manager.newInstance(className));
    

    @Override
    public Object newInstance(String fqcn, ClassLoader classLoader) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException 
        return processAnnotations(manager.newInstance(fqcn, classLoader));
    

    @Override
    public void newInstance(Object o) throws IllegalAccessException, InvocationTargetException, NamingException 
        manager.newInstance(o);
    

    @Override
    public void destroyInstance(Object o) throws IllegalAccessException, InvocationTargetException 
        manager.destroyInstance(o);
    

然后我们添加一个监听器在上下文启动时注入它:

public class SpringJSPEnablerListener implements ServletContextListener 
    @Override
    public void contextInitialized(ServletContextEvent sce) 
        ServletContext context = sce.getServletContext();
        InstanceManager oldManager =  ((InstanceManager) (context.getAttribute(InstanceManager.class.getName())));
        if (!(oldManager instanceof SpringInstanceManager)) 
            InstanceManager springInjectingInstanceManager = new SpringInstanceManager(context,oldManager);
            context.setAttribute(InstanceManager.class.getName(), springInjectingInstanceManager);
        
    

    @Override
    public void contextDestroyed(ServletContextEvent sce) 

然后在 JSP 页面中你可以使用类似这样的东西

<%! @Autowired MyClass myClassInstance %>

它应该可以正常工作。

【讨论】:

以上是关于我们可以在jsp中使用@autowired吗?如果是,那么如何。?的主要内容,如果未能解决你的问题,请参考以下文章

可以在JSR 330中使@Inject成为可选项(如@Autowire(required = false)吗?

您可以将@Autowired 与静态字段一起使用吗?

你可以在@Async 方法中使用@Autowired 属性吗

在Spring框架中我们可以用jsp写jdbc吗

解决非controller使用@Autowired注解注入为null问题

Spring中@Autowired与@Resource的区别