У меня проблема с общим компонентом и одним (из дюжины) приложений. В моем компоненте есть точечные сокращения для многих аннотаций, которые можно использовать в классах и методах в моих приложениях. Когда все аннотации присутствуют в пути к классам, все работает нормально. Но не во всех моих приложениях есть эти зависимости. Быстрое решение - это, конечно, добавить их, но это дает моему приложению много кода, который мне не нужен в этом приложении. Я ищу способ игнорировать ошибку Xlint:invalidAbsoluteTypeName
, как указано здесь: Xlint: invalidAbsoluteTypeName
Итак, что у меня есть:
- У меня много приложений с соединениями Soap / JMS, и все они аннотированы @Annotation
org.springframework.ws.server.endpoint.annotation.Endpoint
. - У меня есть точка в моем общем компоненте (банке):
@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 игнорировалась. Другие обходные пути, такие как разделение pointcut на разные jar-файлы, imho создают слишком много накладных расходов. Есть ли способ заставить Spring AOP просто игнорировать этот pointcut или, например, установить pointcut на 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...)
}
}
Обновление: я попытался создать @NeedsClass("any.package.Class")
, который является аннотацией @Conditional
из spring-context. Класс условия - это 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;
}
}