如何将注释作为为类级别注释定义的建议的参数传递?可能吗?
从这里的帖子我能够得到一个标点,它标识了类中由特定注释标记的所有公共方法.我也可以得到建议.但是,在上面的例子中,我不知道如何将注释变量作为参数传递.
对于方法级注释,我能够获得切入点和建议,我可以将注释作为参数传递,但我不知道如何为类级注释实现相同的注释.
下面的代码有效,但我需要将注释作为下面程序中" LogExecutionTimeByClass " 建议的参数,我无法获得相应的建议或切入点.
注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
String level();
}
Run Code Online (Sandbox Code Playgroud)
方面:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class LogTimeAspect {
/*
* Pointcut to match all the public methods.
*/
@Pointcut("execution(public * *(..))")
public void publicMethod() {}
/*
* Advice for the public methods that are marked with Annotation "LogExecutionTime" and it works as expected no issue.
*/
@Around("publicMethod() && @annotation(annotation) ")
public Object LogExecutionTimeByMethod(final ProceedingJoinPoint joinPoint,final LogExecutionTime annotation) throws Throwable
{
System.out.println("Invoking the method " +joinPoint.getSignature() +" by LogExecutionTimeByMethod Advice");
return joinPoint.proceed();
}
/*
* Pointcut to match all the public methods that are defined under the Class marked with Annotation LogExecutionTime.
*/
@Pointcut("within(@LogExecutionTime *)")
public void beanAnnotatedWithMonitor() {}
@Pointcut("publicMethod() && beanAnnotatedWithMonitor()")
public void publicMethodInsideAClassMarkedWithAtMonitor() {}
/*
* Below Advice works but I need the LogExecutionTime annotation as an argument to below method. (similar to the advice "LogExecutionTimeByMethod"
* defined above)
*/
@Around("publicMethodInsideAClassMarkedWithAtMonitor()")
public Object LogExecutionTimeByClass(final ProceedingJoinPoint joinPoint) throws Throwable
{
System.out.println("Invoking the method " +joinPoint.getSignature() +" by LogExecutionTimeByClass Advice");
//System.out.println("Invoked by " + annotation.value()); //Need the Annotation Variable here as well...
return joinPoint.proceed();
}
/*
*/
}
Run Code Online (Sandbox Code Playgroud)
注释类:
@LogExecutionTime(level="Class_Level_Invocation")
public class Operator {
@LogExecutionTime(level="Method_Level_Invocation")
public void operate() throws InterruptedException {
Thread.sleep(1000);
}
public void operate1() throws InterruptedException {
Thread.sleep(1000);
}
}
Run Code Online (Sandbox Code Playgroud)
主程序:
public class AspectJMain {
public static void main(String[] args) throws InterruptedException {
Operator op = new Operator();
op.operate();
op.operate1();
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Invoking the method void Operator.operate() by LogExecutionTimeByMethod Advice
Invoking the method void Operator.operate() by LogExecutionTimeByClass Advice
Invoking the method void Operator.operate1() by LogExecutionTimeByClass Advice
Run Code Online (Sandbox Code Playgroud)
请注意,使用Spring不是一种选择.我必须使用AspectJ编译器.我编译了我的类并将它们打包为jar并使用ApsectJ编译器使用下面的命令编织方面.
ajc -inpath core.jar -outjar ..\lib\core_woven.jar -1.5
任何指针都会有所帮助.
kri*_*aex 14
解决方案实际上非常简单.我用原生的AspectJ风格编写代码,为了清晰起见,我更喜欢它.您可以轻松地将其调整为@AspectJ注释样式:
public aspect LogTimeAspect {
pointcut publicMethod() : execution(public * *(..));
before(LogExecutionTime logAnn) : publicMethod() && @annotation(logAnn) {
System.out.println(thisJoinPointStaticPart + " -> " + logAnn.level());
}
before(LogExecutionTime logAnn) : publicMethod() && @within(logAnn) {
System.out.println(thisJoinPointStaticPart + " -> " + logAnn.level());
}
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
execution(void Operator.operate()) -> Method_Level_Invocation
execution(void Operator.operate()) -> Class_Level_Invocation
execution(void Operator.operate1()) -> Class_Level_Invocation
Run Code Online (Sandbox Code Playgroud)
如你看到的,
around()建议before(),@annotation()或@within()命名参数绑定有问题的注释.请享用! :-)
更新:为方便起见,这是方面的@AspectJ版本,因为您似乎在使用本机语法调整我的解决方案时遇到问题:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class LogTimeAspect {
@Pointcut("execution(public * *(..))")
public void publicMethod() {}
@Around("publicMethod() && @annotation(logAnn)")
public Object LogExecutionTimeByMethod(ProceedingJoinPoint joinPoint, LogExecutionTime logAnn) throws Throwable {
System.out.println(joinPoint + " -> " + logAnn.level());
return joinPoint.proceed();
}
@Around("publicMethod() && @within(logAnn)")
public Object LogExecutionTimeByClass(ProceedingJoinPoint joinPoint, LogExecutionTime logAnn) throws Throwable {
System.out.println(joinPoint + " -> " + logAnn.level());
return joinPoint.proceed();
}
}
Run Code Online (Sandbox Code Playgroud)
结果将与我的原始版本相同.
| 归档时间: |
|
| 查看次数: |
14350 次 |
| 最近记录: |