AOP
面向切面编程,解决代码复用问题,解耦
场景
日志、性能、权限、事物、异常
核心
方法前后做业务逻辑
原理
静态代理 + 动态代理
技术点
切入点:执行的目标对象
关注点:重复代码(相同点)
切面:关注点形成的类,也叫做切面类
动态代理CGLib与JDK动态代理区别
jdk:需要借口,基于反射
CGlib:只需要子类,基于ASM字节码
jdk动态代理代码
// 每次生成动态代理类对象时,实现了InvocationHandler接口的调用处理器对象
public class InvocationHandlerImpl implements InvocationHandler {
private Object target;// 这其实业务实现类对象,用来调用具体的业务方法
// 通过构造函数传入目标对象
public InvocationHandlerImpl(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
System.out.println("使用jdk动态代理 开启事务");
result = method.invoke(target, args);
System.out.println("使用jdk动态代理 提交事务");
return result;
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// 被代理对象
// IUserDao userDao = new UserDao();
// UserService userService = new UserServiceImpl();
MemberService memberServiceImpl = new MemberServiceImpl();
InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(memberServiceImpl);
ClassLoader loader = memberServiceImpl.getClass().getClassLoader();
Class<?>[] interfaces = memberServiceImpl.getClass().getInterfaces();
// 主要装载器、一组接口及调用处理动态代理实例
MemberService newProxyInstance = (MemberService) Proxy.newProxyInstance(loader, interfaces,
invocationHandlerImpl);
newProxyInstance.memberAdd();
}
}
AOP代码
// 切面类
@Component
@Aspect
public class AopLog {
// aop 编程里面有几个通知: 前置通知 后置通知 运行通知 异常通知 环绕通知
@Before("execution(* com.itmayiedu.service.UserService.add(..))")
public void before() {
System.out.println("前置通知 在方法之前执行...");
}
// 后置通知 在方法运行后执行
@After("execution(* com.itmayiedu.service.UserService.add(..))")
public void after() {
System.out.println("前置通知 在方法之后执行...");
}
// 运行通知
@AfterReturning("execution(* com.itmayiedu.service.UserService.add(..))")
public void returning() {
System.out.println("运行通知");
}
// 异常通知
@AfterThrowing("execution(* com.itmayiedu.service.UserService.add(..))")
public void afterThrowing() {
System.out.println("异常通知");
}
// 环绕通知 在方法之前和之后处理事情
@Around("execution(* com.itmayiedu.service.UserService.add(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
{
// 调用方法之前执行
System.out.println("环绕通知 调用方法之前执行");
proceedingJoinPoint.proceed();// 代理调用方法 注意点: 如果调用方法抛出溢出不会执行后面代码
// 调用方法之后执行
System.out.println("环绕通知 调用方法之后执行");
}
}
网友评论