JavaEE手寫AOP實現,自動代理,AOP面向切面的編程思想

AOP 面向切面的編程思想。 Spring的主要特性之一,今天我整理了一下,小牛試刀,寫了一個Demo分享給大家。  

公司主營業務:成都網站建設、網站制作、移動網站開發等業務。幫助企業客戶真正實現互聯網宣傳,提高企業的競爭能力。成都創新互聯是一支青春激揚、勤奮敬業、活力青春激揚、勤奮敬業、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業文化,感謝他們對我們的高要求,感謝他們從不同領域給我們帶來的挑戰,讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。成都創新互聯推出新北免費做網站回饋大家。

切面最主要的功能是在不影響主業務方法邏輯的情況下,在執行業務方法之前或之后加入執行代碼。
在JavaEE中最常見的莫過于事務控制, 使得程序員只需關注核心業務邏輯,而無需關注事務相反非業務而又必須要的代碼。 

切面的主要組件有:  

    1、切面(@Aspect)。 

    2、切點(@Pointcut)、

    3、通知方法(@Advise),主要有3個

             1、執行前通知- @Before

             2、執行后通知- @After

             3、環繞通知- @Around

 關系圖如下:

JavaEE手寫AOP實現,自動代理, AOP 面向切面的編程思想

AOP項目展開截圖:

JavaEE手寫AOP實現,自動代理, AOP 面向切面的編程思想

InstanceFactory 源碼:

package com.hianzuo.aop;


import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by Ryan
 * On 2017/10/5.
 */
public class InstanceFactory {
    private static final HashMap<Class<?>, Object> classBeanMap = new HashMap<>();
    private static final HashMap<String, Object> beanNameMap = new HashMap<>();
    private static final HashMap<Class<? extends Annotation>, List<AspectAdviceMethod>> mAspectPointcutMethodListMap = new HashMap<>();

    public static <T> T getInstance(Class<T> clazz) {
        return (T) classBeanMap.get(clazz);
    }

    public static <T> T getInstance(String beanName) {
        return (T) classBeanMap.get(beanName);
    }

    public static void init(String pnScan) {
        List<Class<?>> classes = ClassUtil.getClasses(pnScan);
        for (Class<?> clazz : classes) {
            if (isAspectClazz(clazz)) {
                initAspect(clazz);
            }
        }
        for (Class<?> clazz : classes) {
            if (isBeanClazz(clazz)) {
                initBean(clazz);
            }
        }
    }

    private static void initAspect(Class<?> aspectClazz) {
        Method[] methods = aspectClazz.getMethods();
        Object obj;
        try {
            obj = aspectClazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        for (Method method : methods) {
            if (method.isAnnotationPresent(Before.class)) {
                Before adviceBefore = method.getAnnotation(Before.class);
                List<AspectAdviceMethod> adviceList = getAspectAdviceList(Before.class);
                adviceList.add(new AspectAdviceMethod(adviceBefore.value(), adviceBefore.order(), obj, method));
            }
            if (method.isAnnotationPresent(After.class)) {
                After adviceAfter = method.getAnnotation(After.class);
                List<AspectAdviceMethod> adviceList = getAspectAdviceList(After.class);
                adviceList.add(new AspectAdviceMethod(adviceAfter.value(), adviceAfter.order(), obj, method));
            }
            if (method.isAnnotationPresent(Around.class)) {
                Around adviceAround = method.getAnnotation(Around.class);
                List<AspectAdviceMethod> adviceList = getAspectAdviceList(Around.class);
                adviceList.add(new AspectAdviceAroundMethod(adviceAround.value(), adviceAround.order(), obj, method));
            }
        }

    }

    private static List<AspectAdviceMethod> getAspectAdviceList(Class<? extends Annotation> adviceClazz) {
        List<AspectAdviceMethod> methodList = mAspectPointcutMethodListMap.get(adviceClazz);
        if (null == methodList) {
            methodList = new ArrayList<>();
            mAspectPointcutMethodListMap.put(adviceClazz, methodList);
        }
        return methodList;
    }

    private static boolean isAspectClazz(Class<?> aClass) {
        if (aClass.isAnnotationPresent(Aspect.class)) {
            return true;
        }
        return false;
    }

    private static void initBean(Class<?> beanClazz) {
        Class<?>[] interfaces = beanClazz.getInterfaces();
        if (null == interfaces) return;
        for (Class<?> anInterface : interfaces) {
            String beanName = getBeanName(anInterface);
            Object obj = newInstanceProxyClass(anInterface, beanClazz);
            beanNameMap.put(beanName, obj);
            classBeanMap.put(anInterface, obj);
        }
    }

    private static Object newInstanceProxyClass(Class<?> anInterface, Class<?> beanClazz) {
        try {
            Object targetObj = beanClazz.newInstance();
            return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), new Class<?>[]{anInterface}, new AspectHandler(targetObj, mAspectPointcutMethodListMap));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static String getBeanName(Class<?> anInterface) {
        return anInterface.getSimpleName();
    }

    private static boolean isBeanClazz(Class<?> aClass) {
        if (aClass.isAnnotationPresent(Component.class)) {
            return true;
        }
        return false;
    }
}
AspectHandler 源碼:
package com.hianzuo.aop;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.*;

/**
 * Created by Ryan
 * On 2017/10/5.
 */
class AspectHandler implements InvocationHandler {
    private Object targetObj;
    private HashMap, List> mAspectPointcutMethodListMap;
    private HashMap> mBeforeMethodMap = new HashMap<>();
    private HashMap> mAfterMethodMap = new HashMap<>();
    private HashMap mAroundMethodMap = new HashMap<>();

    public AspectHandler(Object targetObj, HashMap, List> map) {
        this.targetObj = targetObj;
        this.mAspectPointcutMethodListMap = map;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        List beforeMethods = getBeforeMethodList(method);
        JointPoint beforePoint = new JointPoint().setTargetObj(targetObj).setProxy(proxy).setMethod(method).setArgs(args);
        for (AspectAdviceMethod adviceMethod : beforeMethods) {
            adviceMethod.invoke(beforePoint);
        }
        AspectAdviceAroundMethod aroundMethod = getAroundMethodList(method);
        Object obj;
        if (null != aroundMethod) {
            obj = aroundMethod.invoke(beforePoint);
        } else {
            obj = method.invoke(targetObj, args);
        }
        List afterMethods = getAfterMethodList(method);
        JointPoint afterPoint = new JointPoint().setTargetObj(targetObj).setProxy(proxy).setMethod(method).setArgs(args).setResult(obj);
        for (AspectAdviceMethod adviceMethod : afterMethods) {
            adviceMethod.invoke(afterPoint);
        }
        return obj;
    }

    private AspectAdviceAroundMethod getAroundMethodList(Method method) {
        if (mAroundMethodMap.containsKey(method)) return mAroundMethodMap.get(method);
        List adviceMethods = mAspectPointcutMethodListMap.get(Around.class);
        if (null == adviceMethods) return null;
        List list = new ArrayList<>();
        for (AspectAdviceMethod adviceMethod : adviceMethods) {
            AspectAdviceAroundMethod adviceAroundMethod = (AspectAdviceAroundMethod) adviceMethod;
            if (adviceAroundMethod.match(method)) {
                list.add(adviceAroundMethod);
            }
        }
        AspectAdviceAroundMethod aroundMethod = null;
        if (!list.isEmpty()) {
            sortAdviceList(list);
            AspectAdviceAroundMethod upMethod = null;
            for (AspectAdviceAroundMethod adviceAroundMethod : list) {
                if (null == aroundMethod) aroundMethod = adviceAroundMethod;
                if (null != upMethod) {
                    upMethod.setNextMethod(adviceAroundMethod);
                }
                upMethod = adviceAroundMethod;
            }
        }
        mAroundMethodMap.put(method, aroundMethod);
        return aroundMethod;
    }

    private static void sortAdviceList(List<? extends AspectAdviceMethod> list) {
        Collections.sort(list, (Comparator) (o1, o2) -> {
            Integer order1 = o1.getPointMethodOrder();
            Integer order2 = o2.getPointMethodOrder();
            return order1.compareTo(order2);
        });
    }

    private List getAfterMethodList(Method method) {
        return getAspectAdviceMethods(After.class, mAspectPointcutMethodListMap, mAfterMethodMap, method);
    }

    private List getBeforeMethodList(Method method) {
        return getAspectAdviceMethods(Before.class, mAspectPointcutMethodListMap, mBeforeMethodMap, method);
    }

    private static List getAspectAdviceMethods(Class<? extends Annotation> adviceClass, HashMap, List> dataMap, HashMap> methodMap, Method method) {
        List aspectAdviceMethods = methodMap.get(method);
        if (null != aspectAdviceMethods) return aspectAdviceMethods;
        aspectAdviceMethods = new ArrayList<>();
        methodMap.put(method, aspectAdviceMethods);
        List methods = dataMap.get(adviceClass);
        if (null == method) return aspectAdviceMethods;
        for (AspectAdviceMethod adviceMethod : methods) {
            if (adviceMethod.match(method)) {
                aspectAdviceMethods.add(adviceMethod);
            }
        }
        sortAdviceList(aspectAdviceMethods);
        return aspectAdviceMethods;
    }
}

分享名稱:JavaEE手寫AOP實現,自動代理,AOP面向切面的編程思想
網址分享:http://m.kartarina.com/article46/pihdhg.html

成都網站建設公司_創新互聯,為您提供網站設計公司小程序開發服務器托管關鍵詞優化手機網站建設網站內鏈

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都網站建設公司
主站蜘蛛池模板: 无码毛片视频一区二区本码| 国产无遮挡无码视频免费软件| 无码伊人66久久大杳蕉网站谷歌| 亚洲AV无码一区二区三区电影| 国产在线拍揄自揄拍无码视频| 日韩人妻无码一区二区三区| AV无码精品一区二区三区宅噜噜 | 无码精品黑人一区二区三区| 无码里番纯肉h在线网站| 国产精品无码国模私拍视频| 中文无码精品一区二区三区| 一本久道综合在线无码人妻| 国产AV无码专区亚洲AV琪琪| 伊人久久精品无码麻豆一区| 东京热av人妻无码| 97精品人妻系列无码人妻| 亚洲AV无码成人精品区大在线| 亚洲中文字幕无码mv| 少妇无码?V无码专区在线观看| 色综合色国产热无码一| 国产成人无码精品一区在线观看| 一本久道综合在线无码人妻| 好硬~好爽~别进去~动态图, 69式真人无码视频免 | 日韩乱码人妻无码中文字幕视频| 亚洲AV无码乱码在线观看代蜜桃| 国产成人AV一区二区三区无码| 亚洲精品~无码抽插| 亚洲中文字幕久久精品无码2021| 亚洲VA中文字幕无码一二三区 | 亚洲AV综合色区无码一二三区 | 国产精品无码一区二区在线观| AV无码精品一区二区三区| 国产麻豆天美果冻无码视频| 伊人久久无码精品中文字幕 | 日韩av无码一区二区三区| 久久久久久无码国产精品中文字幕 | 中文字幕人妻三级中文无码视频| 亚洲av无码国产精品色在线看不卡 | 亚洲日韩精品无码专区加勒比| 亚洲国产精品无码中文lv| 亚洲国产成人精品无码区在线观看|