AOP
面向切面編程,解決代碼復用問題享甸,解耦
場景
日志、性能孔庭、權(quán)限尺上、事物、異常
核心
方法前后做業(yè)務(wù)邏輯
原理
靜態(tài)代理 + 動態(tài)代理
技術(shù)點
切入點:執(zhí)行的目標對象
關(guān)注點:重復代碼(相同點)
切面:關(guān)注點形成的類圆到,也叫做切面類
動態(tài)代理CGLib與JDK動態(tài)代理區(qū)別
jdk:需要借口怎抛,基于反射
CGlib:只需要子類,基于ASM字節(jié)碼
jdk動態(tài)代理代碼
// 每次生成動態(tài)代理類對象時,實現(xiàn)了InvocationHandler接口的調(diào)用處理器對象
public class InvocationHandlerImpl implements InvocationHandler {
private Object target;// 這其實業(yè)務(wù)實現(xiàn)類對象芽淡,用來調(diào)用具體的業(yè)務(wù)方法
// 通過構(gòu)造函數(shù)傳入目標對象
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動態(tài)代理 開啟事務(wù)");
result = method.invoke(target, args);
System.out.println("使用jdk動態(tài)代理 提交事務(wù)");
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();
// 主要裝載器马绝、一組接口及調(diào)用處理動態(tài)代理實例
MemberService newProxyInstance = (MemberService) Proxy.newProxyInstance(loader, interfaces,
invocationHandlerImpl);
newProxyInstance.memberAdd();
}
}
AOP代碼
// 切面類
@Component
@Aspect
public class AopLog {
// aop 編程里面有幾個通知: 前置通知 后置通知 運行通知 異常通知 環(huán)繞通知
@Before("execution(* com.itmayiedu.service.UserService.add(..))")
public void before() {
System.out.println("前置通知 在方法之前執(zhí)行...");
}
// 后置通知 在方法運行后執(zhí)行
@After("execution(* com.itmayiedu.service.UserService.add(..))")
public void after() {
System.out.println("前置通知 在方法之后執(zhí)行...");
}
// 運行通知
@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("異常通知");
}
// 環(huán)繞通知 在方法之前和之后處理事情
@Around("execution(* com.itmayiedu.service.UserService.add(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
{
// 調(diào)用方法之前執(zhí)行
System.out.println("環(huán)繞通知 調(diào)用方法之前執(zhí)行");
proceedingJoinPoint.proceed();// 代理調(diào)用方法 注意點: 如果調(diào)用方法拋出溢出不會執(zhí)行后面代碼
// 調(diào)用方法之后執(zhí)行
System.out.println("環(huán)繞通知 調(diào)用方法之后執(zhí)行");
}
}