我试图通过完成一个记录函数执行时间的非常简单的函数来学习Aspects和自定义注释。我有以下方面和注释和注释函数,但是当我调用带注释的函数时,方法代码不会被调用。如何将注释与方面联系起来?
此外,我尝试将文件声明为一个方面而不是带有@Aspect的类,并且还删除了'@annotation(Benchmark)'并且没有尝试传入注释但它似乎永远不会起作用。
@Benchmark Annotation:
package net.tia.util.aspects;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Benchmark {
public boolean logReturnValue() default false;
public String description() default "";
}
方面
package net.tia.util.aspects;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.text.MessageFormat;
@Component
@Aspect
public class BenchmarkAspect {
private static final Logger logger = Logger.getLogger(BenchmarkAspect.class);
@Around(value = "@annotation(Benchmark)")
public Object benchmarkFunctionExecution(final ProceedingJoinPoint joinPoint, final Benchmark benchmark) throws Throwable {
final long startMillis = System.currentTimeMillis();
Object retVal = null;
try {
System.out.println("Starting timed operation");
retVal = joinPoint.proceed();
return retVal;
} finally {
final long duration = System.currentTimeMillis() - startMillis;
String logMessage = MessageFormat.format("{0} Call to {1} took {2}ms", annotation.description(), joinPoint.getSignature(), duration);
if(annotation.logReturnValue() && (retVal != null)){
logMessage += " Returned: " + retVal.toString();
}
logger.debug(logMessage);
}
}
}
调用我在已经存在的从端点调用的@Service bean上声明的随机函数。
@Benchmark(logReturnValue = true, description = "Overall Time")
public String dummyFunc() {
log.info("Attempting to call aspect");
{
配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
"
>
<!-- enable custom annotations for benchmarking -->
<aop:aspectj-autoproxy/>
<!-- Annotation-driven non-MVC classes -->
<context:annotation-config/>
<context:component-scan base-package="net.tia.extensions,net.tia.sec" />
<beans profile="ldap">
<bean id="AuthenticationProvider" class="net.tia.authentication.LdapAuthenticationProviderImpl">
<property name="userDetailsService" ref="localUserDetailsService"/>
<property name="authenticator">
<bean class="net.tia.authentication.LdapAuthenticatorImpl">
<property name="pricipalPattern">
<value>tia\#login#</value>
</property>
<property name="securityContextSource">
<bean class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://127.0.0.1:452/"/>
</bean>
</property>
</bean>
</property>
</bean>
</beans>
<beans profile="altAuth">
<bean id="siteAuthenticationProvider" class="net.tia.authentication.siteAuthenticationProviderImpl">
<property name="userDetailsService" ref="localUserDetailsService"/>
</bean>
<bean id="singleSignOnIdentityDriver" class="net.tia.authentication.siteIdentityDriver"/>
</beans>
</beans>
答案 0 :(得分:1)
我的语法是否正确
@Around
?
语法在documentation。
中定义您已提供
execution(@net.tia.util.aspects.Benchmark * *(..)), && @annotation(Benchmark)
首先,,
无效。其次,execution
是不必要的。 Spring AOP切入点只能匹配方法调用,而您似乎想要所有方法(public
真的),@annotation
的使用等同于您尝试使用的execution
。
由于您还想在连接点中使用注释,因此只需要
@Around(value = "@annotation(annotation)")
括号内的annotation
是指您的方法参数。
这是一个完整的例子
@ComponentScan
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Sample {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Sample.class);
ctx.getBean(Foo.class).dummyFunc();
}
}
@Component
class Foo {
private static final Logger logger = LoggerFactory.getLogger(Foo.class);
@Benchmark
public String dummyFunc() {
logger.info("real method");
return "sads";
}
}
@Component
@Aspect
class BenchmarkAspect {
private static final Logger logger = LoggerFactory.getLogger(BenchmarkAspect.class);
@Around(value = "@annotation(benchmark)")
public Object benchmarkFunctionExecution(final ProceedingJoinPoint joinPoint, final Benchmark benchmark) throws Throwable {
System.out.println("intercepted");
return joinPoint.proceed();
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Benchmark {
}