Tapestry 5 和 Spring beans 具有相同的接口

发布于 2024-08-29 16:44:11 字数 584 浏览 5 评论 0原文

我在 Tapestry 5 和 Spring 集成方面遇到问题。如果我有多个实现相同接口的 bean,并且我尝试使用 @Inject 注释注入它们,就会出现问题。当然我有一个例外。

我发现一个 教程 说在这种情况下我必须使用 < code>@Service 注释也是如此,但现在我得到了

org.apache.tapestry5.internal.services.TransformationException
Error obtaining injected value for field 
com.foo.pages.Foo.testService: Service 
id 'someServiceIDeclaredInSpringContextFile' is not defined by any module...

无论如何,问题是:如何将实现相同接口的两个不同的 spring bean 注入 Tapestry 5 页面?

I have a problem with Tapestry 5 and Spring integration. Problem occurs if I have a multiple beans that implement the same interface and I try to inject them with @Inject annotation. Of course I got an exception.

I found a tutorial that says that in that case I have to use @Service annotation too but now I'm getting

org.apache.tapestry5.internal.services.TransformationException
Error obtaining injected value for field 
com.foo.pages.Foo.testService: Service 
id 'someServiceIDeclaredInSpringContextFile' is not defined by any module...

Anyway, question is: How can I inject two different spring beans, that implement a same interface, into Tapestry 5 page?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寄居人 2024-09-05 16:44:11

我解决了这个问题。

首先,我做了一个新的注释

public @interface Bean {
    String value();
}

,只要有多个 bean 实现相同的接口,我就使用它

@Inject
@Bean("springBeanName")
Service foo;

然后我更改了 org.apache.tapestry5.internal.spring.SpringModuleDef

private ContributionDef createContributionToMasterObjectProvider() {
  ....
  public void contribute(ModuleBuilderSource moduleSource, 
                ServiceResources resources,
                OrderedConfiguration configuration) {
    ....
    switch (beanMap.size()) {
           case 0:
             return null;
           case 1:
             Object bean = beanMap.values().iterator().next();
             return objectType.cast(bean);
           default:
             Bean annotation = annotationProvider.getAnnotation(Bean.class);
             Object springBean = null;
             String beanName = null;

             if (annotation != null) {
               beanName = annotation.value();
               springBean = beanMap.get(beanName);
             } else {
               String message = String.format(
                 "Spring context contains %d beans assignable to type %s: %s.",
                 beanMap.size(),
                 ClassFabUtils.toJavaClassName(objectType),
                 InternalUtils.joinSorted(beanMap.keySet()));
               throw new IllegalArgumentException(message);
             }
             if (springBean != null) {
               return objectType.cast(springBean);
             } else {
               String message = String.format(
                 "Bean [%s] of type %s doesn't exists. Available beans: %s",
                 beanName, ClassFabUtils.toJavaClassName(objectType),
                 InternalUtils.joinSorted(beanMap.keySet()));
               throw new IllegalArgumentException(message);
             }
           }
         }
       };

I solved this problem.

First I made a new annotation

public @interface Bean {
    String value();
}

and I use this wherever I have this one of multiple beans implementing same interface

@Inject
@Bean("springBeanName")
Service foo;

Then I changed org.apache.tapestry5.internal.spring.SpringModuleDef

private ContributionDef createContributionToMasterObjectProvider() {
  ....
  public void contribute(ModuleBuilderSource moduleSource, 
                ServiceResources resources,
                OrderedConfiguration configuration) {
    ....
    switch (beanMap.size()) {
           case 0:
             return null;
           case 1:
             Object bean = beanMap.values().iterator().next();
             return objectType.cast(bean);
           default:
             Bean annotation = annotationProvider.getAnnotation(Bean.class);
             Object springBean = null;
             String beanName = null;

             if (annotation != null) {
               beanName = annotation.value();
               springBean = beanMap.get(beanName);
             } else {
               String message = String.format(
                 "Spring context contains %d beans assignable to type %s: %s.",
                 beanMap.size(),
                 ClassFabUtils.toJavaClassName(objectType),
                 InternalUtils.joinSorted(beanMap.keySet()));
               throw new IllegalArgumentException(message);
             }
             if (springBean != null) {
               return objectType.cast(springBean);
             } else {
               String message = String.format(
                 "Bean [%s] of type %s doesn't exists. Available beans: %s",
                 beanName, ClassFabUtils.toJavaClassName(objectType),
                 InternalUtils.joinSorted(beanMap.keySet()));
               throw new IllegalArgumentException(message);
             }
           }
         }
       };
池予 2024-09-05 16:44:11

听起来您要么在为 @Service 注释提供的名称中存在拼写错误,要么您实际上没有使用您期望的名称定义 bean。如果没有更多信息,很难确定,因为还有其他一些可能性。

It sounds like you either have a typo in the name give to the @Service annotation, or you have not actually defined the bean with the name that you are expecting. Without more information, it is hard to tell for sure, as there are also some other possibilities.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文