开发者

Tapestry 5 and Spring beans with same interface

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?


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);
             }
           }
         }
       };


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜