首页 > 解决方案 > 通过Controller方法获取bean和applicationContext的区别

问题描述

通过 SpringApplicationContext 从 Controller 方法获取 bean 实例时遇到问题。我在 Controller 方法中需要的是一个填充良好的 class 实例B。类定义B如下:

@Component
public class ADep {

}

@Component
public class A {
    @Autowired
    private ADep aDep;

    public void printDep() {
        System.out.println("aDep is " + aDep);
    }
}

@Component
public class B extends A {
    public void printAMethod() {
        super.printDep();
    }
}

当调用以下 Controller 方法时:

@CrossOrigin
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE, path = "/method1")
public MappingJacksonValue method1(HttpServletRequest request, HttpServletResponse response, B b) throws Exception {
    b.printAMethod();
    return null;
}

我看到以下回复:

aDep is null

如果我从应用程序上下文中获取它,而不是在 Controller 方法中获取 bean,则响应是不同的:

@Autowired
private ApplicationContext applicationContext;

@CrossOrigin
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE, path = "/hardware")
public MappingJacksonValue getHardware(HttpServletRequest request, HttpServletResponse response) throws Exception {
    B b = applicationContext.getBean(B.class);
    b.printAMethod();
    return null;
}

结果:

aDep is ADep@2e468dfa

我需要的是一个 bean 实例,就像后一种情况一样。如何在不使用 SpringApplicationContext 的情况下在 Controller 方法中获取它?

标签: javaspringautowired

解决方案


您正在尝试将 B 类型的 b 对象作为参数传递,因此在这种情况下您必须创建并提供 b 对象并将其传递给方法,我认为您正在给这个参数一个空值,但是如果您想要您可以使用 @Autowired 代替应用上下文,因为 B 已经是一个组件,像这样:

@Autowired
private B b;

@CrossOrigin
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE, path = "/hardware")
public MappingJacksonValue getHardware(HttpServletRequest request, HttpServletResponse response) throws Exception {
    b.printAMethod();
    return null;
}

编辑:

要更改bean的范围,不同的bean针对不同的请求可以在类@Scope(value = WebApplicationContext.SCOPE_REQUEST)上方添加注解B


推荐阅读