简体   繁体   English

无法自动连线工作或进行组件扫描

[英]Unable to get Autowired to work or do a component scan

I'm using Spring for the first time and even though I feel like I'm familiar with the core IoC concept, I'm having trouble getting the @Autowired configuration working. 我是第一次使用Spring,即使我觉得自己熟悉核心IoC概念,也无法使@Autowired配置正常工作。 I've created this github to demonstrate (stack: basic service using Jersey/Tomcat/Spring/Maven): 我创建了这个github进行演示(堆栈:使用Jersey / Tomcat / Spring / Maven的基本服务):

https://github.com/dkwestbr/autowired_example https://github.com/dkwestbr/autowired_example

I'm not using any sort of xml configuration (either for Spring or Tomcat). 我没有使用任何类型的xml配置(用于Spring或Tomcat)。 I can start the server and map to my Jersey end point successfully using mvn clean tomcat7:run but my service is hitting a NullPointerException because the object I'm trying to Autowire isn't being initialized by the Spring framework. 我可以使用mvn clean tomcat7:run启动服务器并成功映射到我的Jersey端点,但是我的服务遇到NullPointerException mvn clean tomcat7:run因为Spring框架没有初始化我尝试自动mvn clean tomcat7:run的对象。

Here is the break down of my current makeup: 这是我目前的妆容分解图:

Why isn't spring detecting/initializing my autowired variable? 为什么不弹簧检测/初始化我的自动接线变量? I've been reading through tutorials for a while now and am at my wits end. 我已经阅读了一段时间的教程,并且精疲力尽。 It doesn't help that most tutorials are written using xml configurations. 大多数教程都是使用xml配置编写的,这无济于事。


Below are the specific code snippets which I'm referencing above: 以下是我上面引用的特定代码段:

The class with the variable I'm trying to initialize via the @Autowired annotation: 我尝试通过@Autowired注释初始化的带有变量的类:

@Path("/foo")
public class WebEndpoint {

    @Autowired
    private IStringGetter getTheThing;

    @GET
    @Path("/bar")
    @Produces(MediaType.TEXT_HTML)
    public String getStuff() {
        System.out.println(getTheThing.getItGood());
        return String.format("<html><body>Hello - %s</body></html>", getTheThing.getItGood());
    }
}

My config: 我的配置:

@Configuration
@ComponentScan(basePackages = {"dkwestbr.spring.autowired.example.**"})
public class AppConfig {

    @Bean
    private static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Configuration
    @PropertySource("classpath:configuration.properties")
    static class Production { }

    @Configuration
    @Profile("test")
    @PropertySource("classpath:configuration.properties")
    static class Test { }
}

Where the config is being loaded: 加载配置的位置:

public class Initializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext context) throws ServletException {
        AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
        appContext.register(AppConfig.class);
        context.addListener(new ContextLoaderListener(appContext));

        Map<String, String> filterParameters = new HashMap<>();

        // set filter parameters
        filterParameters.put("com.sun.jersey.config.property.packages", "dkwestbr.spring.autowired.example");
        filterParameters.put("com.sun.jersey.config.property.JSPTemplatesBasePath", "/WEB-INF/app");
        filterParameters.put("com.sun.jersey.config.property.WebPageContentRegex", "/(images|css|jsp)/.*");

        // register filter
        FilterRegistration.Dynamic filterDispatcher = context.addFilter("webFilter", new ServletContainer());
        filterDispatcher.setInitParameters(filterParameters);
        filterDispatcher.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
    }

}

The @Configuration / Bean definition that I'm hoping would map to the @Autowired variable: 我希望将@Configuration / Bean定义映射到@Autowired变量:

@Component
public class A implements IStringGetter {

    @Bean
    public IStringGetter getTheThing() {
        return new A();
    }

    @Override
    public String getItGood() {
        return "I am an A";
    }

}

UPDATE : I'm providing the stack trace on request (This is line 20: System.out.println(getTheThing.getItGood()); ).... 更新 :我应要求提供堆栈跟踪(这是第20行: System.out.println(getTheThing.getItGood()); )....

java.lang.NullPointerException
    dkwestbr.spring.autowired.example.WebEndpoint.getStuff(WebEndpoint.java:20)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:606)
    com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
    com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
    com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
    com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
    com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
    com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
    com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
    com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
    com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
    com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
    com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

Taking a quick look at your classes, it seems to me like you aren't integrating Spring with Jersey. 快速浏览一下您的课程,在我看来,您似乎没有将Spring和Jersey集成在一起。 The ServletContainer will scan and create its own instance of your WebEndpoint class, but it has no knowledge of the Spring context available in the ServletContext . ServletContainer将扫描并创建自己的WebEndpoint类实例,但是不了解ServletContext中可用的Spring上下文。

For complete Spring-Jersey integration, take a look at this tutorial . 要完全实现Spring-Jersey集成,请看一下本教程 You will need to switch to SpringServlet and add a new library that binds the two. 您将需要切换到SpringServlet并添加一个将两者绑定在一起的新库。


As for your configuration, the @Bean annotation only makes sense in the context of a @Configuration annotated class. 对于您的配置, @Bean批注仅在带有@Configuration批注的类的上下文中才有意义。 This doesn't make any sense 这没有任何意义

@Component
public class A implements IStringGetter {    
    @Bean
    public IStringGetter getTheThing() {
        return new A();
    }    
    @Override
    public String getItGood() {
        return "I am an A";
    }    
}

Get rid of the @Bean method. 摆脱@Bean方法。 With a @ComponentScan , @Component annotated classes will be instantiated and the bean will be added to the context. 使用@ComponentScan ,将实例化@Component注释的类,并将Bean添加到上下文中。 Also changed your AppConfig @ComponentScan to @ComponentScan您的AppConfig @ComponentScan更改为

@ComponentScan(basePackages = {"dkwestbr.spring.autowired.example"})

It recurs through that package. 它通过该包重复出现。

Your two nested @Configuration classes also serve no purpose as it stands. 您的两个嵌套@Configuration类也没有任何作用。

For beans not managed by Spring use extends SpringBeanAutowiringSupport and it should work. 对于不是由Spring管理的bean,请使用extends SpringBeanAutowiringSupport ,它应该可以工作。 In the above example make class WebEndpoint extend SpringBeanAutowiringSupport 在上面的示例中,使类WebEndpoint扩展SpringBeanAutowiringSupport

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 自动接线,无需组件扫描或设置器/获取器 - Autowired without component scan or setter/getter 由于事务传播无法自动连接组件 - Due Transaction propagation unable autowired component Java-Spring:上下文初始化期间发生NullPointerException(使用@ Component,@ Autowired,context:component-scan) - Java-Spring: NullPointerException during context initialization (Using @Component, @Autowired, , context:component-scan) 正在使用 @Component 强制使用 @Autowired 使用<context:component-scan base-package="org.controller"/> - is using @Component compulsory for using @Autowired using <context:component-scan base-package="org.controller"/> @Autowired 的构造函数调用如何工作? - How do constructor calls with @Autowired work? 无法使用@ Autowired处理bean - Can't get@Autowired to work with beans 如何在另一个类中使用@Service注释类作为@Autowired bean,该类位于Service类的组件扫描包之外? - How to use @Service annotated class as an @Autowired bean in another class which is outside the component scan package of the Service class? 我在 Spring 5.3.18 上的组件扫描不起作用 - My component scan on Spring 5.3.18 does not work Runnable @Component类中的@Async不允许它获得Autowired - @Async inside a Runnable @Component class is not letting it get Autowired 如果所有类不在同一个包中,则Spring @autowired不起作用 - Spring @autowired do not work if all classes are not in the same package
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM