Java Spring AOP:我可以忽略由指向我不使用的类的切入点引起的 Xlint:invalidAbsoluteTypeName 错误吗?

Jeroen van Dijk-Jun

我有一个关于通用组件和一个(十几个)应用程序的问题。我的组件有许多注释的切入点,可以在我的应用程序的类和方法中使用。当类路径上存在所有注释时,一切正常。但并非在我的所有应用程序中都有这些依赖项。当然,快速修复是添加它们,但这会给我的应用程序提供很多我在该应用程序中不需要的代码。我正在寻找一种方法来忽略Xlint:invalidAbsoluteTypeName此处所述的错误:Xlint:invalidAbsoluteTypeName

所以我有:

  • 我有许多带有 Soap/JMS 连接的应用程序,并且所有应用程序都使用 @Annotation 进行注释org.springframework.ws.server.endpoint.annotation.Endpoint
  • 我在通用组件(jar)中有我的切入点: @Around("within(@org.springframework.ws.server.endpoint.annotation.Endpoint *)")

结果是:

  • 所有具有 Spring WS 依赖项以及我的通用组件的应用程序都没有问题
  • 没有注释的应用程序无法启动java.lang.IllegalArgumentException: warning no match for this type name: org.springframework.ws.server.endpoint.annotation.Endpoint [Xlint:invalidAbsoluteTypeName](很明显,请参阅链接)

所以问题看起来像Xlint:invalidAbsoluteTypeName 我不想添加我没有使用的 Spring 依赖项。我只想忽略这个 AOP 切入点。其他解决方法,例如将切入点拆分到不同的 jar 恕我直言,会产生过多的开销。有没有办法让 Spring AOP 忽略这个切入点,或者例如将切入点设置为 st 就像 if-exists(class)?

要说明为什么我认为分离会导致太多开销,请查看我的方面结构:

@Aspect
public class PerformanceLoggingAspect {
    private LogWriter logWriter;

    @Inject
    public PerformanceLoggingAspect(LogWriter logWriter) {
        this.logWriter = logWriter;
    }

    @Around("within(@org.springframework.web.bind.annotation.RestController *)")
    public Object withinARestController(ProceedingJoinPoint pjp) throws Throwable {
        return proceedWithLogging(pjp, MetingType.REST);
    }

    @Around("within(@org.springframework.ws.server.endpoint.annotation.Endpoint *)")
    public Object withinAnEndpoint(ProceedingJoinPoint pjp) throws Throwable {
        return proceedWithLogging(pjp, MetingType.BERICHT);
    }

    @Around("within(@javax.inject.Named *)")
    public Object withinAService(ProceedingJoinPoint pjp) throws Throwable {
        return proceedWithLogging(pjp, MetingType.SERVICE);
    }

    private Object proceedWithLogging(ProceedingJoinPoint pjp, String metingType) throws Throwable {
        (... Working code (performance logging) if the annotation is on the classpath...)
    }
}

更新:我尝试创建一个来自 spring-context@NeedsClass("any.package.Class")@Conditional注释。条件类是ClasspathCondition检查类加载器是否可以加载给定类的。但是错误发生在条件得到评估之前,所以我担心这是一个死胡同。但如果你很好奇:

@NeedsClass我试过注释

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Documented
    @Conditional(ClasspathCondition.class)
    public @interface NeedsClass {
        String[] value();
    }

Condition实施。我在这里登录,但从未被写入

    public class ClasspathCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            try {
                String[] classes = (String[]) metadata.getAnnotationAttributes(NeedsClass.class.getName()).get("classes");
                for (String clazz : classes) {
                    ClassUtils.resolveClassName(clazz, context.getClassLoader());
                }
                return true;
            } catch (Throwable t) { /* noOp() */}
            return false;
        }
    }
Jeroen van Dijk-Jun

现在我有一个解决方法

  • 我用以下方法创建了一个超类:

    protected Object proceedWithLogging(ProceedingJoinPoint pjp, String metingType) throws Throwable {
        (... code which adds performance logging ...)
    }
    
  • 我创建了 4 个子类,每个子类都有@Aspect注释,还有 1 个调用 super 的方法。例如,这个针对 JMS:

    @Aspect
    public class JmsPerformanceLogger extends PerformanceLoggingAspect {
        @Inject
        private LogWriter logWriter;
    
        @Around("within(@org.springframework.ws.server.endpoint.annotation.Endpoint *)")
        public Object withinAnEndpoint(ProceedingJoinPoint pjp) throws Throwable {
            return proceedWithLogging(pjp, MetingType.BERICHT);
        }
    }
    
  • 不利的一面是,我必须在我的应用程序中配置我需要的所有不同 bean,而且我无法添加一个简单的配置文件,如下所示,所有 bean 都已预配置:

    @Configuration
    public class PerformanceloggingConfig {
    
        @Bean
        public LogWriter performanceLogWriter(){
            return new DefaultLogWriter();
        }
    
        @Bean
        public JmsPerformanceLogger jmsPerformanceLogger(){
            return new JmsPerformanceLogger();
        }
        @Bean
        public RestPerformanceLogger restPerformanceLogger(){
            return new RestPerformanceLogger();
        }
        @Bean
        public ServicesPerformanceLogger servicesPerformanceLogger(){
            return new ServicesPerformanceLogger();
        }
        @Bean
        public DaoPerformanceLogger daoPerformanceLogger(){
            return new DaoPerformanceLogger();
        }
    }
    

    因此也不是自动配置类的方便注释:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Import(PerformanceloggingConfig.class)
    public @interface EnablePerformanceLogging {
    
    }
    

    但是现在在我需要时添加这 4 个 bean,可以区分每个应用程序。但是当然这仍然是一种解决方法,因为我想使用@EnablePerformanceLogging它并完成它。如果有人有更好的答案,请告诉我

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档