AOP術語:【基於動態代理和cglib代理】
Target【目標類】:需要被代理的類。例如:UserService.
Joinpoint【連接點】:可能被攔截的方法。
Pointcut【切入點】:已經被增強的連接點。
Advice【通知/增強】:增強代碼:例如:after方法和befor方法。
Weaving【織入】:把增強Advice應用到目標對象Target中,創建新的代理對象Proxy的過程。
Proxy【代理對象】
Aspect【切面】:切入點Pointcut和通知Advice的結合。
圖解:
JDK動態代理實現AOP小案例:
目錄結構:
目標結構實現:【UserService】
public interface UserService {
public void AddUser();
public void UpdateUser();
public void DeleteUser();
}
目標接口實現類:【UserServiceImpl】
public class UserServiceImpl implements UserService {
@Override
public void AddUser() {
System.out.println("添加成功");
}
@Override
public void UpdateUser() {
System.out.println("更新成功");
}
@Override
public void DeleteUser() {
System.out.println("刪除成功");
}
}
通知類:【這裏放的都是目標對象需要增強的方法們】
/**
*
* @author jishuai
* @category 切面類【Aspect】
*/
public class MyAspect {
public void Befor() {
System.out.println("開啓事務");
}
public void After() {
System.out.println("結束事務");
}
}
切面類:【將切入點和通知結合】
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyBeanFactory {
public static UserService CreatUserService() {
// 創建目標類
UserService target = new UserServiceImpl();
//創建切面類
MyAspect myAspect = new MyAspect();
/**
* 生成代理類 將目標類和切面類結合 【這就是所謂的切面】
* loader:類加載器 一般採用:當前類名.class
* 也可採用:目標類的加載器->目標類名.getClass().getClassLoader();
* Class[] interfaces: 代理類需要實現的所有接口。方式一:目標類.getClass().getInterfaces(); 只能獲得當前類的接口,不能獲得父元素的接口
* 方式二:new Class[]{UserService.class}; 這個方式獲得多個類的接口。
* InvocationHandler:處理類,接口,採用匿名內部類
*
*/
//代理對象
UserService userServiceProx = (UserService)Proxy.newProxyInstance(
target.getClass().getClassLoader(),
new Class[] {UserService.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//執行切面類的前方法
myAspect.Befor();
// 執行目標方法
Object obj = method.invoke(target, args);
myAspect.After();
//執行切面類的前方法
return obj;
}
});
return userServiceProx;
}
}
測試類:
import org.junit.Test;
public class MyTest {
@Test
public void f() {
UserService userService = MyBeanFactory.CreatUserService();
userService.AddUser();
System.out.println("-------------");
userService.UpdateUser();
System.out.println("-------------");
userService.DeleteUser();
}
}
執行結果:
CGLIB動態代理實現AOP小案例:
目錄結構:
目標類:UserService
public class UserService {
public void AddUser() {
System.out.println("添加員工成功");
}
public void UpdateUser() {
System.out.println("更新員工成功");
}
public void DeleteUser() {
System.out.println("刪除員工成功");
}
}
通知類:MyAspect
public class MyAspect {
public static void Befor() {
System.out.println("開始事務");
}
public static void After() {
System.out.println("結束事務");
}
}
切面類:【MyBeanFactory】將目標類和通知結合起來 實現MethodInterceptor接口 還得生成一個工具代理類
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class MyBeanFactory implements MethodInterceptor {
// 生成目標對象 聚合目標對象
private UserService target;
// 代理工廠構造函數
public MyBeanFactory(UserService target) {
this.target = target;
}
// 該方法返回代理對象
public Object createUserServiceProxy() {
// 創建一個工具類
Enhancer enhancer = new Enhancer();
// 設置父類
enhancer.setSuperclass(target.getClass());
// 設置回調函數
enhancer.setCallback(this);
// 創建子類對象,即代理對象
Object proxy = enhancer.create();
return proxy;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// 執行前方法
MyAspect.Befor();
// 執行目標對象方法
Object object = method.invoke(target, objects);
// 執行後方法
MyAspect.After();
return object;
}
}
測試類:
import org.junit.Test;
public class MyTest {
@Test
public void f() {
UserService userService = new UserService();
MyBeanFactory beanFactory = new MyBeanFactory(userService);
UserService userServiceProxy = (UserService)beanFactory.createUserServiceProxy();
userServiceProxy.AddUser();
System.out.println("---------");
userServiceProxy.UpdateUser();
System.out.println("---------");
userServiceProxy.DeleteUser();
}
}
執行結果: