Java Spring AOP:我可以忽略 Xlint:invalidAbsoluteTypeName 由我不使用的 类 切入点引起的错误吗?
Java Spring AOP: Can I ignore Xlint:invalidAbsoluteTypeName error which caused by pointcuts to classes which I don't use?
我有一个关于通用组件和一个(十几个)应用程序的问题。我的组件对许多注释有切入点,可以在我的应用程序的 classes 和方法中使用。当所有注释都出现在 class 路径上时,一切正常。但并非在我所有的应用程序中我都有这些依赖项。快速修复当然是添加它们,但这会给我的应用程序提供很多我在该应用程序中不需要的代码。我正在寻找一种方法来忽略此处所述的 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]
(很明显,请参阅 link)
所以问题看起来像 Xlint:invalidAbsoluteTypeName 但是 我不想添加 Spring 依赖项我没有用。我只想忽略这个 AOP 切入点。其他解决方法,如将切入点拆分到不同的罐子恕我直言,会产生太多开销。有没有办法让 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...)
}
}
更新: 我尝试创建一个 @NeedsClass("any.package.Class")
这是来自 [=74= 的 @Conditional
注释]-语境。条件 class 是一个 ClasspathCondition
,它检查 class 加载程序是否可以加载给定的 class。但是错误发生在条件被评估之前,所以我担心这是一个死胡同。但如果你很好奇:
我试过的@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;
}
}
现在我有一个解决方法:
我用以下方法创建了一个超级class:
protected Object proceedWithLogging(ProceedingJoinPoint pjp, String metingType) throws Throwable {
(... code which adds performance logging ...)
}
我创建了 4 个 subclasses,每个带有 @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,而且我不能 添加一个简单的配置文件,如下所示,所有 beans 预配置:
@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();
}
}
因此也不是自动配置的方便注释 class:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(PerformanceloggingConfig.class)
public @interface EnablePerformanceLogging {
}
但是现在在我需要的时候添加这 4 个 bean,可以区分每个应用程序。但当然这仍然是一种解决方法,因为我想使用 @EnablePerformanceLogging
并完成它。如果有人有更好的答案,请告诉我
我有一个关于通用组件和一个(十几个)应用程序的问题。我的组件对许多注释有切入点,可以在我的应用程序的 classes 和方法中使用。当所有注释都出现在 class 路径上时,一切正常。但并非在我所有的应用程序中我都有这些依赖项。快速修复当然是添加它们,但这会给我的应用程序提供很多我在该应用程序中不需要的代码。我正在寻找一种方法来忽略此处所述的 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]
(很明显,请参阅 link)
所以问题看起来像 Xlint:invalidAbsoluteTypeName 但是 我不想添加 Spring 依赖项我没有用。我只想忽略这个 AOP 切入点。其他解决方法,如将切入点拆分到不同的罐子恕我直言,会产生太多开销。有没有办法让 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...)
}
}
更新: 我尝试创建一个 @NeedsClass("any.package.Class")
这是来自 [=74= 的 @Conditional
注释]-语境。条件 class 是一个 ClasspathCondition
,它检查 class 加载程序是否可以加载给定的 class。但是错误发生在条件被评估之前,所以我担心这是一个死胡同。但如果你很好奇:
我试过的@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;
}
}
现在我有一个解决方法:
我用以下方法创建了一个超级class:
protected Object proceedWithLogging(ProceedingJoinPoint pjp, String metingType) throws Throwable { (... code which adds performance logging ...) }
我创建了 4 个 subclasses,每个带有
@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,而且我不能 添加一个简单的配置文件,如下所示,所有 beans 预配置:
@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(); } }
因此也不是自动配置的方便注释 class:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Import(PerformanceloggingConfig.class) public @interface EnablePerformanceLogging { }
但是现在在我需要的时候添加这 4 个 bean,可以区分每个应用程序。但当然这仍然是一种解决方法,因为我想使用
@EnablePerformanceLogging
并完成它。如果有人有更好的答案,请告诉我