JavaEE手寫AOP實(shí)現(xiàn),自動(dòng)代理,AOP面向切面的編程思想

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

公司主營(yíng)業(yè)務(wù):成都網(wǎng)站建設(shè)、網(wǎng)站制作、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)推出新北免費(fèi)做網(wǎng)站回饋大家。

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

切面的主要組件有:  

    1、切面(@Aspect)。 

    2、切點(diǎn)(@Pointcut)、

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

             1、執(zhí)行前通知- @Before

             2、執(zhí)行后通知- @After

             3、環(huán)繞通知- @Around

 關(guān)系圖如下:

JavaEE手寫AOP實(shí)現(xiàn),自動(dòng)代理, AOP 面向切面的編程思想

AOP項(xiàng)目展開截圖:

JavaEE手寫AOP實(shí)現(xiàn),自動(dòng)代理, 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實(shí)現(xiàn),自動(dòng)代理,AOP面向切面的編程思想
網(wǎng)址分享:http://muchs.cn/article46/pihdhg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、小程序開發(fā)、服務(wù)器托管、關(guān)鍵詞優(yōu)化手機(jī)網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司