0

CDI 拡張機能を使用して、実行時に JAX-RS リソースを検出し、それらを Java SE 環境のさまざまなベース URI で自動的に公開しようとしています。javax.ws.rs.core.Application可能であれば、アプリケーション自体を拡張する必要はありません。

RestEasy のドキュメントと javadoc を読みましたが@ApplicationPath、実行時に変更する明白な方法を見つけることができませんでした。

私が模索している 1 つのアイデアは、おそらく AnnotatedType CDI 拡張機能を使用して、ベース URI をプログラムで生成javax.ws.rs.core.Applicationおよび設定し、それを org.jboss.resteasy.spi.ResteasyDeployment` として公開することです。@ApplicationPath

これを行う他の/より良い方法はありますか?

編集:

CDI 拡張イベントを試行して、JAX-RS リソースProcessAnnotatedTypeを変更します。@javax.ws.rs.Path

<X> void process(@Observes ProcessAnnotatedType<X> pat) {
  if (!pat.getAnnotatedType().isAnnotationPresent(javax.ws.rs.Path.class)) {
    return;
  }
  final AnnotatedType<X> org = pat.getAnnotatedType();
  AnnotatedType<X> wrapped = new AnnotatedType<X>() {
    @Override
    public <T extends Annotation> T getAnnotation(final Class<T> annotation) {
    if (javax.ws.rs.Path.class.equals(annotation)) {
      class PathLiteral extends AnnotationLiteral<javax.ws.rs.Path> implements javax.ws.rs.Path {
        @Override
        public String value() {
          return "change_me/" + (javax.ws.rs.Path) org.getAnnotation(annotation);
        }
      }
      return (T) new PathLiteral();
    } else {
      return org.getAnnotation(annotation);
    }
  }
  pat.setAnnotatedType(wrapped);
}

...その後、ブートストラップの後、使用してBeanを構築するとjavax.enterprise.inject.spi.BeanManager、次のコードが「change_me/....」を出力することが期待されていました

Set<Bean<?>> beans = beanManager.getBeans(jaxrsClass);
for (Bean<?> bean : beans) {
  CreationalContext cc = bm.createCreationalContext(bean);
  Object jaxrs = bean.create(cc);
  Path p = jaxrs.getClass().getAnnotation(Path.class);
  System.out.println(p.value());
}

...しかし、これは機能しません。javax.ws.rs.PathJAX-RS リソース 'jaxrsClass' については変更されていません。

なにが問題ですか?

4

2 に答える 2

0

これが信頼できる方法でできるとは思えません。それはおそらく、どちらが最初に発生するかにかかっています。CDI ブートストラップまたは JAX-RS、もちろん将来的に、または他のアプリケーション サーバーでは、すべてが並行して実行される可能性があります。

それは確かにクールなアイデアですが。RestEasy フォーラムで彼らは何と言いましたか?

于 2012-11-12T05:53:09.743 に答える
0

私たちはすでにそのようなアプローチを使用しています。

この機能を使用して、サブリソース ロケーターを使用し、偽装の力を利用しています。

起動時に、@Path で注釈が付けられたすべてのリソースのクラスパスをスキャンしています。その後、パスを抽出し、Names/@Named を使用してリソースをバインドします。そのため、リソースは後で名前の助けを借りて注入できます。

bind(..).annotatedWith(Names.named("path")).to(..)

次のステップでは、サブリソース ロケータを含むリソースが必要です。

@Path("{name}")
public Object find(@PathParam("name") name){
    return injector.getInstance(..);
}

このアプローチを使用して、実行時にそれらをバインドし、元の注釈付きパスを変更することもできます。

于 2012-11-13T08:31:30.773 に答える