我正在尝试使用spring aop在Spring框架的方面使用泛型接口和泛型类,我想为使用@EntityController注释的任何类设置父接口:
@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> {
...
}
所以我怎么能做到这一点?还是有另一种选择?你必须记住我正在使用弹簧配置文件,所以使用原生aspectj不是另一种选择。
答案 0 :(得分:1)
让我们暂时假设,如果您按照Spring的文档介绍如何将它集成到Spring项目中,原生AspectJ对您来说不是一个显示器。在这种情况下,你可以做这样的事情(我使用原生的AspectJ语法,因为注释风格的@AspectJ语法从可读性/表达性的角度来看有许多缺点):
与嵌入式方面的接口提供默认实现:
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
如果您不理解我的代码段,请随时提出进一步的问题。