2017-01-02 13 views
0

私は春のプロジェクトで注入する必要のある外部ライブラリからのJavaオブジェクトをいくつか持っています。問題は、ライブラリからのクラスが認識していない任意のスプリングAPIの春のPOJO注入CDIと似ています

私は図書館から私は

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of typeを取得しています@Autowiredを使用してサービスに豆を注入した場合、私のサービスクラスがある

@Path("/test") 
public class TestService { 

    @Autowired 
    SomeOtherClass service; 

    @GET 
    public Response get(){ 
     return Response.ok(service.someMethod()).build(); 
    } 
} 

と以下は、春を意識していない図書館のクラスです。

public class SomeOtherClass { 

    public String someMethod(){ 
     return "Data from library"; 
    } 
} 

私のサービスを呼び出すと、私は例外として

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.SomeOtherClass' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 

**CDI**に注入と同様のプレーンなJavaオブジェクトを春に挿入する方法はありますか? applicationContext.xmlを定義し、xmlにSomeOtherClassを定義してgetBeanを使用する方法がありますが、そのようにしたくありません。他の選択肢はありますか?

注:私は図書館

  1. Cannot use applicationcontext.xml

  2. Cannot @Configuration @Bean to produce beansから来たクラスの100'sを持っているので、

    オプション次は考えることはできません。次のように

+1

'getBean'は' SomeOtherClass'のインスタンスを宣言するだけで '@ Autowired'が動作するだけです。 SpringはマネージドBeanのみを注入します(何かがマネージドBeanでない場合は、CDIのように注入することもありません)。 –

+1

次に春を使わないでください...春の管理されたインスタンスであることが知られているクラスを作成する必要があります。 xmlまたはjavaベースの設定を使用できない(または使用しない)場合は、春に役立つことはあまりありません。 (しかし、あなたはこれらのクラスを検出/スキャンするために春を拡張することができますが、それは内部の知識と春の作業を必要とします)。 –

答えて

3

あなたは@Configurationと@Bean注釈を使用することができます -

を新しいクラスを作成します。

@Configuration 
public class AppConfig { 

    @Bean 
    SomeOtherClass someOtherClassBean(){ return new SomeOtherClass();} 

} 

今自動配線が働くものとします。 実際には、Beanを作成し、Springにそのことを知らせることです。

+0

私はこのオプションを考えましたが、ライブラリからたくさんのクラス(100)があります。 ConfigurationとBeanの作成を避け、Autowireにプレーンオブジェクトを挿入するようSpringに指示する方法はありますか? –

+0

そのコードはコンパイルされません... –

+0

@ M. Deinum編集を参照してください。 – gba

1

たぶん、IoCコンテナにプログラム的に豆を追加してみてください: Add Bean Programmatically to Spring Web App Context

あなたがリンクされ、当該方法のいずれかをインスタンス化して使用したいすべてのクラスを見つける必要があります。

+0

注入を達成するための余分なコードを書くことは、コンテキストファイルやBeanの設定と似ています。私は、java eeのbean-discovery-mode = "ALL"に似た、サポート外のものを探しています –

+1

私はそこに何かがあると確信していません。ほとんどの使用例では、IoCコンテナに入るものを制御することが理にかなっているようです。あなたは何か役に立つと思っていますか?我々に教えてください :-) – gba

1

リフレクションを使用して、プログラムでBean定義を追加できます。

@Override 
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { 
    Reflections ref = new Reflections(new ConfigurationBuilder() 
      .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner()) 
      .setUrls(ClasspathHelper.forPackage(PACKAGE_NAME)) 
      .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix(PACKAGE_NAME)))); 
    ref.getSubTypesOf(Object.class).stream() 
      .forEach(clazz -> { 
       logger.info("Defining pojo bean: {} -> {}", Introspector.decapitalize(clazz.getSimpleName()), clazz.getCanonicalName()); 
       registry.registerBeanDefinition(Introspector.decapitalize(clazz.getSimpleName()), 
         BeanDefinitionBuilder.genericBeanDefinition(clazz).getBeanDefinition()); 
      }); 
} 

次に、これらの豆は他のところで@Autowiredになる可能性があります。 Gist:https://gist.github.com/ftahmed/a7dcdbadb8bb7dba31ade463746afd04

関連する問題