gpt4 book ai didi

java - Spring AOP 中 @DeclareParents 注解中的泛型类型

转载 作者:行者123 更新时间:2023-12-01 12:40:36 25 4
gpt4 key购买 nike

我正在尝试使用 spring aop 在 Spring 框架的一个方面使用通用接口(interface)和通用类,我想为任何用 @EntityController 注释的类设置父接口(interface):

@Component
@MongoProfile
@Aspect
public class EntityMongoControllerAspect<T> {

@DeclareParents(value="@EntityController *",defaultImpl=EntityMongoController.class)
private IEntityController<T> iEntityController;
}

但是 eclipse 总是抛出异常:

java.lang.IllegalStateException
at org.aspectj.weaver.ResolvedTypeMunger.<init>(ResolvedTypeMunger.java:69)
at org.aspectj.weaver.MethodDelegateTypeMunger.<init>(MethodDelegateTypeMunger.java:61)
at org.aspectj.weaver.bcel.AtAjAttributes.handleDeclareParentsAnnotation(AtAjAttributes.java:852)
at org.aspectj.weaver.bcel.AtAjAttributes.readAj5ClassAttributes(AtAjAttributes.java:384)
at org.aspectj.weaver.bcel.BcelObjectType.ensureAspectJAttrib ... ob.java:241)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)

Compile error: IllegalStateException thrown: Use generic type, not raw type

我的entityMongoController代码是:

public class EntityMongoController<T1> {
...
}

那么我怎样才能实现这个目标呢?或者还有其他选择吗?您必须记住,我正在使用 spring 配置文件,因此使用 native aspectj 不是替代方案。

最佳答案

让我们暂时假设,如果您按照 Spring 的文档了解如何将 native AspectJ 集成到您的 Spring 项目中,那么 native AspectJ 对您来说并不是一个阻碍。在这种情况下,您可以执行以下操作(我使用 native AspectJ 语法,因为从可读性/表达能力的角度来看,注释式 @AspectJ 语法有很多缺点):

与嵌入式方面的接口(interface)提供默认实现:

package de.scrum_master.app;

public interface IEntityController<T> {
public void setEntity(T entity);
public T getEntity();

static aspect EntityControllerAspect {
private T IEntityController.entity;
public void IEntityController.setEntity(T entity) { this.entity = entity; }
public T IEntityController.getEntity() { return entity; }

declare parents : @EntityController * implements IEntityController;
}
}

带有示例 main 方法的带注释的类,显示了效果:

package de.scrum_master.app;

import java.lang.reflect.Method;

@EntityController
public class MyAnnotatedController<T> {
public void doSomething() {
System.out.println("Doing something");
}

public static void main(String[] args) {
// Use class type directly so as to call its method
MyAnnotatedController<String> annotatedTextController = new MyAnnotatedController<>();
annotatedTextController.doSomething();

// Print all declared methods (should also show interface methods introduced via ITD)
for (Method method : annotatedTextController.getClass().getDeclaredMethods()) {
if (!method.getName().startsWith("ajc$"))
System.out.println(method);
}

// Prove that class type is compatible with interface type
IEntityController<String> entityTextController = annotatedTextController;
entityTextController.setEntity("foo");
// Would not work here because generic interface type is type-safe:
// entityTextController.setEntity(123);
System.out.println("Entity value = " + entityTextController.getEntity());

// Create another object and directly assign it to interface type
IEntityController<Integer> entityNumberController = new MyAnnotatedController<>();
entityNumberController.setEntity(123);
// Would not work here because generic interface type is type-safe:
// entityNumberController.setEntity("foo");
System.out.println("Entity value = " + entityNumberController.getEntity());
}
}

控制台输出:

Doing something
public static void de.scrum_master.app.MyAnnotatedController.main(java.lang.String[])
public java.lang.Object de.scrum_master.app.MyAnnotatedController.getEntity()
public void de.scrum_master.app.MyAnnotatedController.setEntity(java.lang.Object)
public void de.scrum_master.app.MyAnnotatedController.doSomething()
Entity value = foo
Entity value = 123

如果您不理解我的代码片段,请随时提出进一步的问题。

关于java - Spring AOP 中 @DeclareParents 注解中的泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25140307/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com