JavaEE手写AOP实现,自动代理, AOP 面向切面的编程思想
发表于:2024-11-17 作者:千家信息网编辑
千家信息网最后更新 2024年11月17日,AOP 面向切面的编程思想。 Spring的主要特性之一,今天我整理了一下,小牛试刀,写了一个Demo分享给大家。切面最主要的功能是在不影响主业务方法逻辑的情况下,在执行业务方法之前或之后加入执行代码
千家信息网最后更新 2024年11月17日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安全错误
数据库的锁怎样保障安全
中卫网络安全局
icloud邮箱 服务器
网络安全宣传周主持词开场白
计算机应用软件开发工资
基于人工智能的网络安全防御技术
网络安全现状调研分析
阿里云服务器 udp
服务器等保2.0测评
网络安全英语名句
代理服务器玩lol
评论网络安全法四个有力推动
购买网络技术服务源头好货
steam上超级服务器
中兴g5300服务器中间灯红色
国家网络安全宣传感受
深信服服务器u盘启动
服务器系统故障
三门峡软件开发建设
杭州恩牛网络技术有限待遇
软件开发容易脱发
湖南图书馆有族谱数据库吗
qt数据库没有驱动
优刻得服务器搭建
网站网络安全和保密专栏
android清除数据库
数据库连接方法不用密码和账号
违反网络安全法知识测试答案
洛阳华睿网络技术有限公司
乡镇扶贫办网络安全工作总结
华为服务器服务器管理网口