首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用不使用Spring的@AspectJ语法实现抽象和具体类的方面

使用不使用Spring的@AspectJ语法实现抽象和具体类的方面
EN

Stack Overflow用户
提问于 2014-03-24 00:58:40
回答 1查看 3.2K关注 0票数 1

我正在使用AspectJ实现类级和方法级的注释驱动程序方面,使用基于Spring的AOP在Spring应用程序中使用。

AnnotationTimeoutAspect暴露于Spring应用程序并使用

对于Grails应用程序,设置为Config.groovy grails.spring.bean.packages = ['com.xyz.aspect']<context:component-scan base-package="com.xyz.aspect"/> <aop:aspectj-autoproxy/>

引发以下错误。

解析点剪切时不可用的所需参数名称

当方面和切入点在单个类(没有抽象类和具体类)中实现时,它可以按照预期的方式工作。

当使用JUnit测试类和负载时间编织进行本地测试时,抽象类和具体类分离也能很好地工作。在使用基于Spring代理的AOP场景时,这种方法也不起作用。

我的目标是保持抽象方面的实现和具体方面的切入点,这样我就可以根据我的切入点需求实现多个具体方面。

如果你有什么办法,请告诉我。

混凝土方面

代码语言:javascript
运行
复制
@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";
}

抽象方面

代码语言:javascript
运行
复制
@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);
}

误差

代码语言:javascript
运行
复制
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
EN

回答 1

Stack Overflow用户

发布于 2014-06-26 07:34:08

抽象类中不能有@Pointcut。使用所有切入点创建另一个类,并使其扩展这个类。建议可以留在这里。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22599362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档