AOP實現(xiàn)原理:1.JDK動態(tài)代理

1.概念:AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術。
使用這種AOP方式要求目標類有接口+實現(xiàn)類,如沒有接口只有實現(xiàn)類,則要使用CGLIB的方式。
2.術語:
2.1 target:目標類,需要被代理的類。例如:UserService
2.2 Joinpoint(連接點):所謂連接點是指那些可能被攔截到的方法。例如:所有的方法
2.3 PointCut 切入點:已經(jīng)被增強的連接點。例如:addUser()
2.4 advice 通知/增強,增強代碼。例如:after、before
2.5 Weaving(織入):是指把增強advice應用到目標對象target來創(chuàng)建新的代理對象proxy的過程.
2.6 proxy 代理類
2.7 Aspect(切面): 是切入點pointcut和通知advice的結合
一個線是一個特殊的面。
一個切入點和一個通知,組成成一個特殊的面。
3.代碼
3.1 創(chuàng)建IUserService的接口

public interface IUserService {
//    面向切面編程
    public void addUser();
    public void updateUser();
    public int deleteUser(int id);
}

3.2 UserServiceImpl類實現(xiàn)IUserService接口

public class UserServiceImpl implements IUserService {
    @Override
    public void addUser() {
        System.out.println("Service 添加用戶");
    }

    @Override
    public void updateUser() {
        System.out.println("Service 更新用戶");

    }

    @Override
    public int deleteUser(int id) {
        System.out.println("Service 通過id刪除用戶");

        return 1;
    }
}

3.3 聲明一個面向切面的對象,如我這里寫的是MyAspect

//切面類,代碼增強與切入點的結合
public class MyAspect {
    public void before(){
        System.out.println("開啟事務");
    }

    public void after(){
        System.out.println("提交事務");
    }
}

3.4 實現(xiàn)一個UserService的工廠類

public class UserServiceFactory {
    public static IUserService createUserService(){
//        1.創(chuàng)建目標對象target
        IUserService userService = new UserServiceImpl();

//        2.聲明切面類對象
        MyAspect aspect = new MyAspect();
//        3.把切面類2個方法 應用 目標類
//        3.1 創(chuàng)建JDK代理
        IUserService serviceProxy = (IUserService) Proxy.newProxyInstance(UserServiceFactory.class.getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("方法名:"+method.getName());
                System.out.println("參數(shù):"+args);

//                開始事務
                aspect.before();
                Object o = method.invoke(userService,args);
                System.out.println("JDK代理攔截返回值"+o);
//                結束事務
                aspect.after();
                return o;
            }
        });

        return serviceProxy;
    }
}

3.5 測試

public class Test {
    @Test
    public void Test(){
        IUserService userService = UserServiceFactory.createUserService();
        userService.deleteUser(10);
        userService.add();
        userService.updateUser();
    }
}

結果如下:


image.png
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容