转自:
Aspect注解简介
AOP(Aspect Oriented Programming):面向切面编程
使用预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
AOP是目前编程的一个热点,是Spring框架的重要组成部分
是函数式编程的一部分
使用AOP可以对业务逻辑的各个部分进行隔离
从而使得业务逻辑各部分之间的耦合度降低
提高程序的可重用性
同时提高了开发的效率。
AOP使用场景
如:日志记录,性能统计,安全控制,事务处理,异常处理等代码
AOP的相关注解
AOP可以使用@Aspect这个注解
@Aspect注解的功能:讲当前类标识为一个切面供容器读取
@Pointcut:Pointcut是植入Advice的触发条件
每个Pointcut可定义为2部分:
1.表达式
2.方法签名
方法签名必须是 public及void型
@Around:环绕增强,相当于MethodInterceptor
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterThrowing:异常抛出增强,相当于ThrowsAdvice
@After:final增强,不管是抛出异常或者正常退出都会执行
pointcut代码示例
package com.java265.test.advice;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class AdviceTest {
@Around("execution(* com.abc.service.*.many*(..))")
public Object process(ProceedingJoinPoint point) throws Throwable {
System.out.println("@Around:执行目标方法之前...");
//访问目标方法的参数:
Object[] args = point.getArgs();
if (args != null && args.length > 0 && args[0].getClass() == String.class) {
args[0] = "改变后的参数1";
}
//用改变后的参数执行目标方法
Object returnValue = point.proceed(args);
System.out.println("@Around:执行目标方法之后...");
System.out.println("@Around:被织入的目标对象为:" + point.getTarget());
return "原返回值:" + returnValue + ",这是返回结果的后缀";
}
@Before("execution(* com.abc.service.*.many*(..))")
public void permissionCheck(JoinPoint point) {
System.out.println("@Before:模拟权限检查...");
System.out.println("@Before:目标方法为:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@Before:参数为:" + Arrays.toString(point.getArgs()));
System.out.println("@Before:被织入的目标对象为:" + point.getTarget());
}
@AfterReturning(pointcut="execution(* com.abc.service.*.many*(..))",
returning="returnValue")
public void log(JoinPoint point, Object returnValue) {
System.out.println("@AfterReturning:模拟日志记录功能...");
System.out.println("@AfterReturning:目标方法为:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@AfterReturning:参数为:" +
Arrays.toString(point.getArgs()));
System.out.println("@AfterReturning:返回值为:" + returnValue);
System.out.println("@AfterReturning:被织入的目标对象为:" + point.getTarget());
}
@After("execution(* com.abc.service.*.many*(..))")
public void releaseResource(JoinPoint point) {
System.out.println("@After:模拟释放资源...");
System.out.println("@After:目标方法为:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@After:参数为:" + Arrays.toString(point.getArgs()));
System.out.println("@After:被织入的目标对象为:" + point.getTarget());
}
}
使用annotation
//注解实体类
package com.java265.other;
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 InfoSender {
String value() default "";
String infoContent() default "";
String showInfo() default "";
}
//切面类
@Aspect
@Component("testClass")
public class TestClass {
private Logger logger = LoggerFactory.getLogger(TestClass.class);
/**
* 在所有标记了@InfoSender的方法中切入
* @param joinPoint
* @param result
*/
@AfterReturning(value="@annotation(com.java265.other.InfoSender)", returning="result")//有注解标记的方法,执行该后置返回
public void afterReturning(JoinPoint joinPoint , Object result//注解标注的方法返回值) {
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
Method method = ms.getMethod();
boolean active = method.getAnnotation(InfoSender.class).isActive();
if (!active) {
return;
}
String content = method.getAnnotation(InfoSender.class).infoContent();
}
/**
* 在抛出异常时使用
* @param joinPoint
* @param ex
*/
@AfterThrowing(value="@annotation(com.java265.other.InfoSender)",throwing = "ex")
public void afterThrowing(JoinPoint joinPoint, Throwable ex//注解标注的方法抛出的异常) {
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
Method method = ms.getMethod();
String info = method.getAnnotation(TestClass.class).showInfo();
}
}
//实体类中使用该注解标注方法
@Service("testService ")
public class TestService {
@Override
@InfoSender(infoContent = "java265.comContent", showInfo =
"exception")
public String test(String param) {
return "success";
}
}
注意事项:
配置文件上需加入以下语句