通过Controller方法获取bean和applicationContext之间的区别

时间:2019-04-15 11:17:29

标签: java spring autowired

在通过SpringApplicationContext从Controller方法获取bean实例时出现问题。我在Controller方法中需要的是类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方法中得到它?

2 个答案:

答案 0 :(得分:2)

您试图将类型B的b对象作为参数传递,因此在这种情况下,您必须创建并赋予b对象并将其传递给方法,我认为您正在为该参数赋予null值,但是如果您希望可以使用@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注释

答案 1 :(得分:1)

您的方法中的参数由Spring MVC参数解析器提供。它不会在这里注入bean。我有点惊讶b在这种情况下不为null,也许默认行为是创建此类的新实例,当然在这种情况下aDep为null。