我正在使用AspectJ在类级别和方法级别实现注释驱动程序方面,以用于使用基于Spring代理的AOP的Spring应用程序。
当AnnotationTimeoutAspect暴露于Spring Application并使用时
对于Grails应用程序,设置为Config.groovygrails.spring.bean.packages=['com.xyz.aspect']
或者对于Spring应用程序
引发以下错误。
解析切点时所需的参数名称不可用
当方面和切入点在单个类中实现时(没有抽象和具体的类),它会按预期工作。
当使用JUnit测试类和加载时编织进行本地测试时,抽象类和具体类的分离也可以很好地工作。当与基于Spring代理的AOP场景一起使用时,这一点不起作用。
我的目标是保持抽象方面的实现和具体方面的切入点,这样我就可以根据切入点的需要实现多个具体方面。
如果您有任何解决方法,请告诉我。
具体方面
@Component
@Order(116)
@Aspect
public class AnnotationTimeoutAspect extends AbstractTimeoutAspect {
@Pointcut("execution(@com.xyz.annotation.Timeout * *(..)) && @annotation(timeoutConfig)")
public void executionOfTimeoutMethod(Timeout timeoutConfig) {}
@Pointcut("execution(public * ((@com.xyz.annotation.Timeout *)+).*(..)) " +
"&& within(@com.xyz.annotation.Timeout *) && @target(timeoutConfig) " +
"&& !com.xyz.aspect.SystemArchitecture.groovyMOPMethods()")
public void executionOfAnyPublicMethodInAtTimeoutType(Timeout timeoutConfig) {}
@Pointcut("(executionOfTimeoutMethod(timeoutConfig) || executionOfAnyPublicMethodInAtTimeoutType(timeoutConfig))")
public void timeoutMethodExecution(Timeout timeoutConfig) { }
@DeclareError("execution(@com.xyz.annotation.Timeout * *(..) throws !java.util.concurrent.TimeoutException)")
static final String anError = "Only methods that are declared with throws TimeoutException may have an @Timeout annotation";
}
抽象方面
@Aspect
public abstract class AbstractTimeoutAspect {
protected final Logger log = LoggerFactory.getLogger(getClass());
private static class TimeoutThread extends Thread {
private boolean completed = false;
private ProceedingJoinPoint point;
private Throwable throwable;
private Object value;
public ProceedingJoinPoint getPoint() {
return point;
}
public Throwable getThrowable() {
return throwable;
}
public Object getValue() {
return value;
}
public boolean isCompleted() {
return completed;
}
public void run() {
try {
setValue(point.proceed());
} catch (Throwable t) {
setThrowable(t);
} finally {
setCompleted(true);
}
}
public void setCompleted(boolean completed) {
this.completed = completed;
}
public void setPoint(ProceedingJoinPoint point) {
this.point = point;
}
public void setThrowable(Throwable throwable) {
this.throwable = throwable;
}
public void setValue(Object value) {
this.value = value;
}
}
@Around("executionOfAnyPublicMethodInAtTimeoutType(timeoutConfig)")
public Object timeoutOnClassLevel(final ProceedingJoinPoint point,Timeout timeoutConfig) throws Throwable {
return doTimeout(point,timeoutConfig);
}
@Around("executionOfTimeoutMethod(timeoutConfig)")
public Object timeoutOnMethodLevel(final ProceedingJoinPoint point,Timeout timeoutConfig) throws Throwable {
return doTimeout(point,timeoutConfig);
}
// @Around("timeoutMethodExecution(timeoutConfig)")
public Object doTimeout(final ProceedingJoinPoint point,Timeout2 timeoutConfig) throws Throwable {
log.debug(point + " -> " + timeoutConfig);
Method method = ((MethodSignature) point.getSignature()).getMethod();
TimeoutThread thread = new TimeoutThread();
thread.setDaemon(timeoutConfig.daemon());
thread.setPoint(point);
thread.start();
thread.join(timeoutConfig.value());
if (!thread.isCompleted()) {
throw new TimeoutException("Method " + method + " exceeded timeout of " + timeoutConfig.value() + " milliseconds");
} else if (thread.getThrowable() != null) {
throw thread.getThrowable();
} else {
return thread.getValue();
}
}
@Pointcut
public abstract void executionOfAnyPublicMethodInAtTimeoutType(Timeout timeoutConfig);
@Pointcut
public abstract void executionOfTimeoutMethod(Timeout timeoutConfig);
@Pointcut
public abstract void timeoutMethodExecution(Timeout timeoutConfig);
}
错误
2014-03-23 16:48:01,924 [localhost-startStop-1] DEBUG annotation.ReflectiveAspectJAdvisorFactory - Found AspectJ method: public java.lang.Object com.xyz.aspect.AbstractTimeoutAspect.timeoutOnClassLevel(org.aspectj.lang.ProceedingJoinPoint,com.xyz.annotation.Timeout) throws java.lang.Throwable
2014-03-23 16:48:01,925 [localhost-startStop-1] DEBUG annotation.ReflectiveAspectJAdvisorFactory - Found AspectJ method: public java.lang.Object com.xyz.aspect.AbstractTimeoutAspect.timeoutOnMethodLevel(org.aspectj.lang.ProceedingJoinPoint,com.xyz.annotation.Timeout) throws java.lang.Throwable
Caused by IllegalStateException: Required parameter names not available when parsing pointcut executionOfTimeoutMethod in type com.xyz.aspect.AbstractTimeoutAspect
->> 290 | getDeclaredPointcuts in org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 800 | getDeclaredPointcuts in org.aspectj.weaver.ReferenceType
| 243 | get . . . in org.aspectj.weaver.ResolvedType$PointcutGetter
抽象类中不能有@切入点。用所有切入点创建另一个类,并使其扩展这个类。建议可以留在这里。
来自spring参考文档 Spring建议您只使用@Transactional注释来注释具体的类(以及具体类的方法),而不是注释接口。您当然可以将@Transactional注释放置在接口(或接口方法)上,但只有在使用基于接口的代理时,它才会像您所期望的那样工作。Java注释不是从接口继承的,这意味着如果您使用的是基于类的代理(proxy-target-class=“true”)或基于编织的方面(
我知道抽象类可能包含抽象和具体方法(即主体实现)。我的问题是:子类可以从抽象超类继承/覆盖具体方法吗?其次,它们必须以实现抽象方法的方式实现具体方法吗?
在java中,是否可以使用通配符定义抽象方法,但在实现中使用具体类型 eg: 在这样的抽象类中定义抽象方法 实现如下抽象方法,其中CorporateServer扩展了用户:
问题内容: 当其中的所有方法都是具体的时,有人在声明类抽象时有一些实际的编程情况吗? 问题答案: 好吧,您可能正在使用模板方法模式,其中存在多个都具有默认实现的覆盖点,但是组合的默认实现本身不合法-任何功能实现都必须是子类。 (是的,我不喜欢模板方法模式;)
我在各自的字段中使用了@CreatedBy、@CreatedDate、@LastModifiedBy和@LastModifiedDate注释。通过使用@MappdSuperclass、@EntityListeners,我能够持久化上面的列。 但这不适用于以下情况: 审计员我mpl.java JpaAuditConfiguration。Java语言 在这种情况下,实体B填充了审计列。但实体A并非如此
我想在我即将完成的一些工作中使用builder模式,它在一个层次结构中有几个类。基类将至少有9个字段要启动,各个子类可能会添加2-4个字段。这会很快失控,而builder模式正是出于这个原因吸引了我。我在书籍和文章中初步接触了builder模式。他们是有帮助的,但没有关于如何扩展这种模式。我试图自己实现这一点,但是我在每个子类的构造函数中遇到了麻烦,因为我不知道如何将构建器中收集的数据传递给超级类