有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

grails无法调用需要java的方法。lang.类参数?

我正试图将这个ControllerAnnotationHelper转换成一个服务,我遇到了一些奇怪的问题

No signature of method AnnotationScannerService.findAnnotatedClosures() is applicable for argument types:
(java.lang.Class, java.lang.Class) values: [class MyController, interface MyAnnotationRequired]

以下是原始方法:

private static Map<String, List<Class>> findAnnotatedClosures(
      Class clazz, Class... annotationClasses) {
   def map = [:]
   for (field in clazz.declaredFields) {
      def fieldAnnotations = []
      for (annotationClass in annotationClasses) {
         if (field.isAnnotationPresent(annotationClass)) {
            fieldAnnotations << annotationClass
         }
      }
      if (fieldAnnotations) {
         map[field.name] = fieldAnnotations
      }
   }

   return map
}

和我的:

protected Map<String, List<Class>> findAnnotatedClosures(Class clazz, Class... annotationClasses) {
   def map = [:]
   for (field in clazz.declaredFields) {
      def fieldAnnotations = []
      for (annotationClass in annotationClasses) {
         if (field.isAnnotationPresent(annotationClass)) {
            fieldAnnotations << annotationClass
         }
      }
      if (fieldAnnotations) {
         map[field.name] = fieldAnnotations
      }
   }

   return map
}

通过调用:

public void test_findAnnotatedClosures() {
   Map<String, List<Class>> annotatedClosures =
        annotationScannerService.findAnnotatedClosures(MyController, MyRequiredAnnotation)
}

如何声明此方法,以便使用控制器类和各种注释接口类调用它


共 (4) 个答案

  1. # 1 楼答案

    一般来说,服务中的非公共方法没有多大意义。尤其是在Grails中,这将是一个问题,因为默认情况下服务是事务性的,所以您将使用的实例将是一个代理

    只有公共方法被代理。受保护的方法是有效的,但通常仅在类或子/超类中进行子类化和调用时使用

    所以它可以归结为一个Groovy/Spring的东西。我们习惯于Groovy对访问规则不严格,但Grails服务几乎完全是Springbean——Grails只允许您在Groovy中编写它们,自动创建关联的Springbean,并自动使它们具有事务性(除非禁用)

    将方法设置为静态也是可行的,因为您绕过了代理,直接进入真实的类,Groovy允许您调用它,即使它受到保护

  2. # 2 楼答案

    每个类都是类^{}(我知道这让人困惑)的一个实例,其中类型参数T是“由这个Class对象建模的类的类型”换句话说,你的类MyControllerClass<MyController>类型的对象

    每个类都有一个名为class的隐藏静态字段。如果要访问MyController类本身,请使用声明MyController.class。这将返回Class<MyController>的一个实例,MyController.class可用的所有方法和字段都是任何Class对象可用的方法和字段。例如,^{}

    总之,您的调用代码应该是:

    public void test_findAnnotatedClosures() {
        Map<String, List<Class>> annotatedClosures =
            annotationScannerService.findAnnotatedClosures(MyController.class,
                MyRequiredAnnotation.class)
    }
    

    注:@Stefan Kendall是正确的。如果方法test_findAnnotatedClosures()不依赖于任何实例,那么最好声明它static并从静态上下文引用它,尽管它不是必需的。但这不是重点

  3. # 3 楼答案

    这很奇怪,我无法解释,但只有当方法声明为静态并静态使用时,调用才有效。无法从服务实例调用它

    保持方法静态,它就会工作。如果其他人能解释这一点,我将投赞成票

  4. # 4 楼答案

    也许这取决于groovy版本。groovy 1.7删除了所有泛型类型信息,而不是1.8。正确的方法声明是:

    protected Map<String, List<Class<? extends Annotation>>> findAnnotatedClosures(Class<?> clazz, Class<? extends Annotation>... annotationClasses)
    

    因为^{}