JavaEE手写AOP实现,自动代理, AOP 面向切面的编程思想
发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,AOP 面向切面的编程思想。 Spring的主要特性之一,今天我整理了一下,小牛试刀,写了一个Demo分享给大家。切面最主要的功能是在不影响主业务方法逻辑的情况下,在执行业务方法之前或之后加入执行代码
千家信息网最后更新 2025年02月01日JavaEE手写AOP实现,自动代理, AOP 面向切面的编程思想
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, Object> classBeanMap = new HashMap<>(); private static final HashMap beanNameMap = new HashMap<>(); private static final HashMap , List > mAspectPointcutMethodListMap = new HashMap<>(); public static T getInstance(Class clazz) { return (T) classBeanMap.get(clazz); } public static T getInstance(String beanName) { return (T) classBeanMap.get(beanName); } public static void init(String pnScan) { List > 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 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 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 adviceList = getAspectAdviceList(Around.class); adviceList.add(new AspectAdviceAroundMethod(adviceAround.value(), adviceAround.order(), obj, method)); } } } private static List getAspectAdviceList(Class extends Annotation> adviceClazz) { List 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; }}
业务
方法
面的
事务
代码
切面
源码
逻辑
思想
编程
切点
功能
只需
小牛
常见
情况
截图
是在
核心
特性
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
onethink数据库链接
北京15k工资软件开发
数据库企业管理器哪里打开
怎么看服务器端的安全设置
浙江crm软件开发价格
对软件开发的职业要求
服务器最大内存
2020网络安全大会主题
qt 从数据库读取数据库
常见的四类网络数据库
小米软件开发面试
有趣的讲解网络技术
西安交通基础数据库
沉迷网络安全教育内容
谁有人民日报数据库
互联网科技给农村带来的变化
数据库受限制用户
港股科技互联网etf
iso软件开发过程
学计算机网络技术去什么学校好
e-r数据库设计图
全盛通网络技术有限公司标志
数据库管理信息基本思想
数据库electric
软件开发部门中存在的问题
服务器安全巡查制度
关于软件开发方面的文献
ip网络技术 下载
防网络安全诈骗安全作业
网络安全设备资金申请