JavaEE手写AOP实现,自动代理, AOP 面向切面的编程思想
发表于:2025-12-04 作者:千家信息网编辑
千家信息网最后更新 2025年12月04日,AOP 面向切面的编程思想。 Spring的主要特性之一,今天我整理了一下,小牛试刀,写了一个Demo分享给大家。切面最主要的功能是在不影响主业务方法逻辑的情况下,在执行业务方法之前或之后加入执行代码
千家信息网最后更新 2025年12月04日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安全错误
数据库的锁怎样保障安全
服务器dl380 usb启动
计算机网络技术教师资格证书
戴尔r720服务器回收
惠普塔式服务器维修站
朝阳区大型软件开发经历
软件开发代码是否交付
Dm7数据库备份
战地5哪一个服务器人多
海外服务器的ip
t140服务器尺寸
暗黑4服务器上线
微信小程序 访问阿里云数据库
软件开发公司都有哪些部门
本机连接服务器
宁波软件开发哪个公司好
数据库显示外键表字段
网络安全这项工作
石家庄服务器回收
魔域新端数据库
上海服务软件开发市场
猫眼和电影票房数据库哪个
附加2008数据库文件夹
辨析金融科技与互联网金融的关系
开展网络安全检查需要资质么
装饰效果图软件开发
软件开发合同金额多少
mc和风服务器
软件开发费用支付
网络技术应用的填空题
小三相电机绕组数据库