Spring获取当前的ApplicationContext

Lyn*_*nAs 97 java spring servlets spring-mvc

我正在使用Spring MVC作为我的Web应用程序.我的bean写在" spring-servlet.xml"文件中

现在我有一个类MyClass,我想使用spring bean访问这个类

spring-servlet.xml我写的以下

<bean id="myClass" class="com.lynas.MyClass" />
Run Code Online (Sandbox Code Playgroud)

现在我需要使用它来访问它 ApplicationContext

ApplicationContext context = ??
Run Code Online (Sandbox Code Playgroud)

这样我才能做到

MyClass myClass = (MyClass) context.getBean("myClass");
Run Code Online (Sandbox Code Playgroud)

这该怎么做??

gip*_*ani 149

只需注入它..

@Autowired
private ApplicationContext appContext;
Run Code Online (Sandbox Code Playgroud)

或实现此接口:ApplicationContextAware

  • 我不确定这如何回答这个问题。您无法在不受 Spring 管理的对象中自动连接应用程序上下文。 (3认同)
  • 每次都返回NULL。在这里提到,我在一个既不是“@RestController”也不是“@Component”的普通类中执行此操作 (2认同)

Viv*_*vek 81

我认为这个链接演示了在任何地方获取应用程序上下文的最佳方法,即使在非bean类中也是如此.我发现它非常有用.希望对你来说一样.以下是它的抽象代码

创建一个新类ApplicationContextProvider.java

package com.java2novice.spring;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class ApplicationContextProvider implements ApplicationContextAware{

    private static ApplicationContext context;

    public static ApplicationContext getApplicationContext() {
        return context;
    }

    @Override
    public void setApplicationContext(ApplicationContext ac)
            throws BeansException {
        context = ac;
    }
}
Run Code Online (Sandbox Code Playgroud)

在application-context.xml中添加一个条目

<bean id="applicationContextProvider"
                        class="com.java2novice.spring.ApplicationContextProvider"/>
Run Code Online (Sandbox Code Playgroud)

在注释案例中(而不是application-context.xml)

@Component
public class ApplicationContextProvider implements ApplicationContextAware{
...
}
Run Code Online (Sandbox Code Playgroud)

获取这样的上下文

TestBean tb = ApplicationContextProvider.getApplicationContext().getBean("testBean", TestBean.class);
Run Code Online (Sandbox Code Playgroud)

干杯!!

  • 在`ApplicationContextProvider`上添加`@Component`可以避免在`aplication-context.xml`中进行配置 (4认同)
  • 我的编码与 Vivek 类似。但每次需要从上下文调用 getBean() 时,我都会避免创建新的 ApplicationContextProvider() 。我所做的是拥有 **静态** `ApplicationContextProvider.getApplicationContext()` 方法。然后,当需要当前应用程序上下文时,我调用:`ApplicationContextProvider appContext = ApplicationContextProvider.getApplicationContext()` (2认同)

Jar*_*uba 39

如果你需要从HttpServlet中访问上下文,而HttpServlet本身没有被Spring实例化(因此@Autowire和ApplicationContextAware都不会工作)......

WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
Run Code Online (Sandbox Code Playgroud)

要么

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
Run Code Online (Sandbox Code Playgroud)

至于其他一些回复,请在执行此操作之前三思而后行:

new ClassPathXmlApplicationContext("..."); // are you sure?
Run Code Online (Sandbox Code Playgroud)

...因为这不会给你当前的上下文,而是为你创建它的另一个实例.这意味着1)在这两个应用程序上下文之间不共享大量内存和2)bean.


rzy*_*mek 29

如果你正在实现一个没有被Spring实例化的类,就像你可以使用的JsonDeserializer那样:

WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
MyClass myBean = context.getBean(MyClass.class);
Run Code Online (Sandbox Code Playgroud)

  • 它对我不起作用.我的课程超出了Spring的范畴.我试图使用你的代码,但它给了我一个**null**作为响应.我在谈论`ContextLoader.getCurrentWebApplicationContext()` (4认同)

Hit*_*mar 9

将其添加到您的代码中

@Autowired
private ApplicationContext _applicationContext;

//Add below line in your calling method
MyClass class = (MyClass) _applicationContext.getBean("myClass");

// Or you can simply use this, put the below code in your controller data member declaration part.
@Autowired
private MyClass myClass;
Run Code Online (Sandbox Code Playgroud)

这只会将myClass注入您的应用程序


Jua*_*uan 6

基于Vivek的答案,但我认为以下内容会更好:

@Component("applicationContextProvider")
public class ApplicationContextProvider implements ApplicationContextAware {

    private static class AplicationContextHolder{

        private static final InnerContextResource CONTEXT_PROV = new InnerContextResource();

        private AplicationContextHolder() {
            super();
        }
    }

    private static final class InnerContextResource {

        private ApplicationContext context;

        private InnerContextResource(){
            super();
        }

        private void setContext(ApplicationContext context){
            this.context = context;
        }
    }

    public static ApplicationContext getApplicationContext() {
        return AplicationContextHolder.CONTEXT_PROV.context;
    }

    @Override
    public void setApplicationContext(ApplicationContext ac) {
        AplicationContextHolder.CONTEXT_PROV.setContext(ac);
    }
}
Run Code Online (Sandbox Code Playgroud)

从实例方法写入静态字段是一种不好的做法,而且如果要操纵多个实例,则很危险。