AOP 面向切面的編程思想。 Spring的主要特性之一,今天我整理了一下,小牛試刀,寫了一個Demo分享給大家。
公司主營業務:成都網站建設、網站制作、移動網站開發等業務。幫助企業客戶真正實現互聯網宣傳,提高企業的競爭能力。成都創新互聯是一支青春激揚、勤奮敬業、活力青春激揚、勤奮敬業、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業文化,感謝他們對我們的高要求,感謝他們從不同領域給我們帶來的挑戰,讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。成都創新互聯推出新北免費做網站回饋大家。
切面最主要的功能是在不影響主業務方法邏輯的情況下,在執行業務方法之前或之后加入執行代碼。
在JavaEE中最常見的莫過于事務控制, 使得程序員只需關注核心業務邏輯,而無需關注事務相反非業務而又必須要的代碼。
切面的主要組件有:
1、切面(@Aspect)。
2、切點(@Pointcut)、
3、通知方法(@Advise),主要有3個
1、執行前通知- @Before
2、執行后通知- @After
3、環繞通知- @Around
關系圖如下:
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。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯