0

私は初めて Spring を使用しています。IoC のコア コンセプトに精通しているように感じますが、@Autowired 構成を機能させるのに問題があります。デモ用にこの github を作成しました (スタック: Jersey/Tomcat/Spring/Maven を使用した基本的なサービス):

https://github.com/dkwestbr/autowired_example

私は (Spring または Tomcat のいずれかの) xml 構成を使用していません。サーバーを起動してJerseyエンドポイントに正常にマップできますmvn clean tomcat7:runが、AutowireしようとしているオブジェクトがSpringフレームワークによって初期化されていないため、サービスがNullPointerExceptionにヒットしています。

現在のメイクの内訳は次のとおりです。

スプリングが自動配線された変数を検出/初期化しないのはなぜですか? 私はしばらくの間チュートリアルを読んでいて、頭がいっぱいです。ほとんどのチュートリアルが 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, "/*");
    }

}

私が望んでいる / 定義は、変数にマップされ@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";
    }

}

更新: リクエストに応じてスタック トレースを提供しています (これは 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)
4

2 に答える 2

3

クラスをざっと見てみると、Spring と Jersey を統合していないように思えます。はクラスServletContainerの独自のインスタンスをスキャンして作成しますが、WebEndpointで利用可能な Spring コンテキストを認識していませんServletContext

完全な Spring-Jersey 統合については、このチュートリアルをご覧ください。SpringServlet2 つをバインドする新しいライブラリに切り替えて追加する必要があります。


構成に関しては、注釈は注釈付きクラス@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"})

それはそのパッケージを通して繰り返されます。

ネストされた 2 つ@Configurationのクラスも、現状では何の役にも立ちません。

于 2013-10-10T17:45:45.927 に答える
1

Spring で管理されていない Bean の場合extends SpringBeanAutowiringSupport、動作するはずです。上記の例では、クラスWebEndpointを拡張しますSpringBeanAutowiringSupport

于 2014-07-12T00:41:02.200 に答える