Java 通过控制器方法获取bean和applicationContext之间的区别

Java 通过控制器方法获取bean和applicationContext之间的区别,java,spring,autowired,Java,Spring,Autowired,通过SpringApplicationContext从控制器方法获取bean实例时出现问题。我在控制器方法中需要的是类B的一个填充良好的实例。类B的定义如下: @Component public class ADep { } @Component public class A { @Autowired private ADep aDep; public void printDep() { System.out.println("aDep is " +

通过SpringApplicationContext从控制器方法获取bean实例时出现问题。我在控制器方法中需要的是类
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();
    }
}
调用以下控制器方法时:

@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
如果我从应用程序上下文中获取bean,则响应不同,而不是在控制器方法中获取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,我如何在控制器方法中获得它?

您试图将类型为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,您可以在
B
class

上添加
@scope(value=WebApplicationContext.scope\u request)
注释方法中的参数由Spring MVC参数解析器提供。这里没有注入bean。我有点惊讶,在这种情况下b不是空的,可能默认行为是创建这个类的新实例,当然,在这种情况下,aDep是空的。

在第一种情况下,
b
是该方法的一个参数。无法告诉您如何调用该方法,但很可能您将
null
传递到itA方法参数中,该参数永远不会自动连接,只有类级依赖项才会自动连接。除非您使用全面的AspectJ用法(编译或loadtimeweaving)并使用
@Configured
。那么为什么绑定和自动连接都需要B呢?@M.Deinum,不知道在通过自动连接实例变量调用方法的情况下,实例的可用性是不同的。有没有办法为方法参数获取Autowire类型的功能?尝试在方法变量中使用Autowire,但没有任何差异。没有。不能将bean注入到方法参数中。除非您编写自己的
HandlerMethodArgumentResolver
实现,它可以做到这一点。但是为什么在方法中需要一个自动连接的对象呢?我无法设置B类的作用域来请求。因此,在前面的请求中设置的任何值都保留在类B的实例变量中。使用默认作用域,同一实例在多个请求之间共享,从而保留在以前的请求中设置的字段。