2013-10-10 26 views
0

我第一次使用Spring並且即使我覺得我熟悉核心IoC概念,但我無法使@Autowired配置工作。我創建這個github上展示無法使Autowired工作或執行組件掃描

https://github.com/dkwestbr/autowired_example

我沒有使用任何類型的XML配置(無論是春季或Tomcat)的:(堆棧:使用澤西/ Tomcat的/春/ Maven的基本服務)。我可以啓動服務器並使用mvn clean tomcat7:run成功映射到澤西島終點,但是我的服務正在觸發NullPointerException,因爲我嘗試Autowire的對象沒有被Spring框架初始化。

這是我目前的妝下來休息:

爲什麼不是春檢測/初始化我的自動裝配Autowired變量?我已經閱讀了一段時間的教程,現在正在閱讀。大多數教程都是使用xml配置編寫的,這並沒有幫助。


下面是具體的代碼片段,我上面我引用:

的類變量我試圖通過@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()); 
    } 
} 

我的配置:

@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 { } 
} 

配置被加載的地方:

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, "/*"); 
    } 

} 

即我希望將映射到@Autowired變量@Configuration/Bean定義:

@Component 
public class A implements IStringGetter { 

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

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

} 

UPDATE:我提供關於請求堆棧跟蹤(這是線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) 
+0

我們不想關注鏈接。直接在您的問題中發佈相關的代碼和配置。 –

+0

會做。我認爲這會更簡潔,因爲它涉及多個代碼片段,但我會發布一些代碼。 – Dave

+0

@SotiriosDelimanolis - 我的問題已經更新了代碼。 – Dave

回答

3

以快速瀏覽你的類,它似乎對我來說,你是不是我與澤西結合在一起的春天。 ServletContainer將掃描並創建自己的WebEndpoint類的實例,但它不知道ServletContext中可用的Spring上下文。

對於完整的Spring-Jersey集成,請看this tutorial。您需要切換到SpringServlet並添加一個綁定這兩者的新庫。


至於您的配置,@Bean批註纔有一個@Configuration註解類的上下文意義。這沒有任何意義

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

擺脫@Bean方法。使用@ComponentScan,@Component註釋類將被實例化,並且該bean將被添加到上下文中。也改變了你的AppConfig@ComponentScan

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

它反覆通過該包。

您的兩個嵌套@Configuration類也沒有任何作用。

+0

感謝您的答案,但我仍然有問題。我切換到SpringServlet,但我看到的基本上是一樣的東西。我的新代碼在這裏(以前的代碼已被註釋掉):https://github.com/dkwestbr/autowired_example/blob/master/src/main/java/dkwestbr/spring/autowired/example/Initializer.java – Dave

+0

@dave I已編輯添加一些你應該做的修復。 –

+0

謝謝你的進一步建議,但仍然沒有運氣。我已經實現了你的兩個建議(刪除bean和更改包掃描),現在我仍然看到任何東西。我已經更新了github w /我目前的代碼是什麼樣的。 – Dave

1

對於沒有被Spring管理的豆使用extends SpringBeanAutowiringSupport,它應該工作。 在上例中,使用類WebEndpoint擴展SpringBeanAutowiringSupport