手写IoC和DI后已经实现的类图结构。
AOP [面向方面编程] 面向方面编程增强了类方法的功能,而无需更改类的代码。
我们需要为用户提供基于手写IoC和手写DI的AOP功能,让他们可以通过AOP技术增强类方法的功能。
提供AOP功能!然后呢? ……已经没有了。关键是从上面的定义来理解它。
在上面分析AOP需求的时候,我们引入了相关的概念,比如通知、切入点、编织等。首先我们来看看AOP中我们会接触到的相关概念。
更形象的描述
那么对于上面的相关概念,我们要考虑哪些需要用户提供,哪些需要框架编写?
思考:Advice、Pointcuts、Weaving各自的特点
通过上面的分析,我们需要设计并实现AOP功能。事实上,我们需要设计并实现与上面分析的相关概念相对应的组件。
建议:通知由用户提供。我们使用它们。用户提供的主要内容突出了可变性。我们应该如何设计这个区域呢?这里有两个问题:
。我们应该如何设计这个区域呢?这里有两个问题:
针对这种情况,我们定义了一组标准的接口,用户通过实现接口类来提供自己不同的逻辑。可以吗? 这里有一个重要的设计原则大家要注意:如何通过面向接口编程来应对变化!!! 让我们先定义一个空接口。我们可以先思考一下为什么要定义一个空接口? 1.2 Advice特征分析 建议特点:可选时机,可以选择在方法执行之前、之后或执行时增强功能 根据以上情况,我们可以分析出Advice通知的几种情况 预增强-之前 返回后 周围 最终通知-之后 异常通知-抛出 这么多情况,我们该如何实施呢?我们可以定义标准的接口方法,让用户实现它,并提供各种特定的增强功能。那么这四种增强相关方法的定义是什么?我们来一一分析。 1.3 各类通知分析 1.3.1 正面增强 预增强 :方法执行前的增强。 问题 1:可能需要哪些参数? 目的是加强方法。需要的是方法相关的信息。当我们使用它的时候,它能给我们的是当前要执行的方法相关的信息 问题2:运行时方法有哪些信息? 方法本身方法 Object该方法所属的对象Object 方法参数Object[] 问题3:预增强的返回值是多少? 方法执行前进行增强,不需要返回值! 公共 接口MethodBeforeAdvice扩展 建议 { /** * 实现此方法进行预增强 * * @param method * 方法 * @param args * 方法参数 * @param target * 增强目标对象 * @throws可投掷 */ 无效 之前(方法方法,对象[]参数,对象目标)抛出可抛出; } 1.3.2 最终通知 最后通知:方法执行后的增强 问题 1:可能需要哪些参数? 方法本身方法 Object该方法所属的对象Object 方法参数Object[] 方法的返回值Object可能没有 问题2:它的返回值是多少? 这就需要在After中检查返回的结果是否允许改变。如果指定返回值只能使用不能修改,则不需要返回值 公共 接口 AfterAdvice 扩展建议 { /** * 实现该方法,并提供后增强 * * @param returnValue * 返回值 * @param方法 *增强方法 * @param args * 方法的参数 * @param 目标 * @投掷可投掷 */ void after(对象返回值,方法方法,对象[]参数,对象目标) 投掷可投掷;} 1.3.3 发布通知 后增强:方法执行后的增强 问题1:他可能需要的参数 方法本身方法 Object该方法所属的对象Object 方法参数Object[] 方法Object的返回值 问题2:它的返回值是多少? 这就需要在After中检查返回的结果是否允许改变。如果指定返回值只能使用不能修改,则不需要返回值 公共 接口归还后建议延伸 建议 { /** * 实现此方法并提供 AfterRetun 增强 * * @param returnValue * 返回值 * @param方法 *增强方法 * @param args * 方法参数 * @param目标 * @投掷可投掷 * / void 返回后(对象返回值,方法方法,对象[]参数,对象目标) 投掷 可投掷;} 1.3.4 环绕通知 环绕增强:环绕增强方法 问题1:他可能需要的参数 方法本身方法 Object该方法所属的对象Object 方法参数Object[] 问题2:它的返回值是面试? 方法被它包裹,即方法会被它执行,并且需要返回方法的返回值 公共 接口方法拦截器扩展 建议 { /** * 增强方法的周边(前后处理)和异常处理。方法实现时需要调用目标方法。 * * @param方法 * * @param args * @param target * 对象该方法所属的方法 * @return 对象 返回值 * @throws Throwable */对象 调用(方法方法,对象[]参数,对象目标)抛出可抛出;} 1.3.5 异常通知 异常通知增强:增强方法执行过程中异常的处理 问题 1:可能需要哪些参数? 必须有例外 可能需要方法本身 方法 可能需要方法所属的对象 可能需要方法参数 Object[] 问题2:它的返回值是多少? 这就需要在After中检查返回的结果是否允许改变。如果指定返回值只能使用不能修改,则不需要返回值 公共 接口 抛出建议扩展 建议 { 无效 afterThrowing(方法方法,对象[]参数,对象目标,异常ex)抛出可抛出;} 1.4 建议设计 结合上面的分析,我们可以画出Advice的系统图 2.切入点 2.1 Pointcut 的特点是: 可用性:由用户指定 可变性:用户可以灵活指定 多点:用户可以选择多点增强 2.2 切入点分析 为用户提供一些东西,让他们可以灵活地指定多个方法点,我们仍然可以理解! 思考:入口点是让用户指定应该增强哪些方法点。那么这些方法点如何表明可以满足上述需求呢? 分析: 指定了哪些方法?是描述信息吗? 如何指定方法? 超载怎么办? 123实际上需要完整的方法签名 com.boge.spring.aop.Girl.dbj(男孩,时间)com.boge.spring.aop.Girl.dbj(男孩,女孩,时间) 我们要进一步分析:如何实现多点、灵活,并在一个描述中指定某个类的某些方法? 某个包下某个类的某个方法 某个包下所有类中的所有方法 某个包下所有类中以do开头的方法 某个包下以service结尾的类中以do开头的方法 ….. 也就是说,我们需要这样一个表达式来灵活地描述上述信息。 该表达式表达的内容为: 每个部分有什么要求? 包名:具有父子特征,必须能够模糊匹配 类名:需要模糊匹配 方法名称:模糊匹配 参数类型:可以有多个参数 那么我们设计的表达式就会被我们用来决定是否需要增强某个类的某个方法。这个决策过程应该是什么样的? 我们根据您的需求选择是: AspectJ官网:http://www.gsm-guard.net/aspectj 切入点表达式要匹配的对象是目标方法的方法名。因此,执行表达式显然就是方法的签名。注意,表达式中带[]的部分表示该部分可以省略,各部分之间用空格分隔。可以使用以下符号 示例: 相关推荐 Linux 查看网卡的MAC地 Symantec Backup Symantec Backup Python 入门基础知识(1 Python 入门基础知识(1 如何提高QPS? ORA Linux下alternati CentOS7.2上编译安装P centos7下编译安装php 在centos7.6上编译安装 MySQL事务隔离级别和数据一 了解JAVA的垃圾收集机制 Zookeeper简述 360手机N5怎么样?真机评测 努比亚Z17配置曝光:降频版骁 安卓版微信多开6.3.8,如何 设置WordPress文章中特 mysql所有更新都被锁了吗| vue.js是前端还是后端 攀升9周年店庆盛大来袭 多款台 想要畅爽开黑还是首选台式机 武 暑期开启畅爽开黑模式 武极高性 stm32串口引脚(stm32
这里有一个重要的设计原则大家要注意:如何通过面向接口编程来应对变化!!!
让我们先定义一个空接口。我们可以先思考一下为什么要定义一个空接口?
建议特点:可选时机,可以选择在方法执行之前、之后或执行时增强功能
根据以上情况,我们可以分析出Advice通知的几种情况
这么多情况,我们该如何实施呢?我们可以定义标准的接口方法,让用户实现它,并提供各种特定的增强功能。那么这四种增强相关方法的定义是什么?我们来一一分析。
预增强 :方法执行前的增强。
问题 1:可能需要哪些参数?
目的是加强方法。需要的是方法相关的信息。当我们使用它的时候,它能给我们的是当前要执行的方法相关的信息
问题2:运行时方法有哪些信息?
问题3:预增强的返回值是多少?
方法执行前进行增强,不需要返回值!
公共 接口MethodBeforeAdvice扩展 建议 { /** * 实现此方法进行预增强 * * @param method * 方法 * @param args * 方法参数 * @param target * 增强目标对象 * @throws可投掷 */ 无效 之前(方法方法,对象[]参数,对象目标)抛出可抛出; }
最后通知:方法执行后的增强
问题2:它的返回值是多少?
这就需要在After中检查返回的结果是否允许改变。如果指定返回值只能使用不能修改,则不需要返回值
公共 接口 AfterAdvice 扩展建议 { /** * 实现该方法,并提供后增强 * * @param returnValue * 返回值 * @param方法 *增强方法 * @param args * 方法的参数 * @param 目标 * @投掷可投掷 */ void after(对象返回值,方法方法,对象[]参数,对象目标) 投掷可投掷;}
后增强:方法执行后的增强
问题1:他可能需要的参数
公共 接口归还后建议延伸 建议 { /** * 实现此方法并提供 AfterRetun 增强 * * @param returnValue * 返回值 * @param方法 *增强方法 * @param args * 方法参数 * @param目标 * @投掷可投掷 * / void 返回后(对象返回值,方法方法,对象[]参数,对象目标) 投掷 可投掷;}
环绕增强:环绕增强方法
问题2:它的返回值是面试?
方法被它包裹,即方法会被它执行,并且需要返回方法的返回值
公共 接口方法拦截器扩展 建议 { /** * 增强方法的周边(前后处理)和异常处理。方法实现时需要调用目标方法。 * * @param方法 * * @param args * @param target * 对象该方法所属的方法 * @return 对象 返回值 * @throws Throwable */对象 调用(方法方法,对象[]参数,对象目标)抛出可抛出;}
异常通知增强:增强方法执行过程中异常的处理
公共 接口 抛出建议扩展 建议 { 无效 afterThrowing(方法方法,对象[]参数,对象目标,异常ex)抛出可抛出;}
结合上面的分析,我们可以画出Advice的系统图
为用户提供一些东西,让他们可以灵活地指定多个方法点,我们仍然可以理解!
思考:入口点是让用户指定应该增强哪些方法点。那么这些方法点如何表明可以满足上述需求呢?
分析:
com.boge.spring.aop.Girl.dbj(男孩,时间)com.boge.spring.aop.Girl.dbj(男孩,女孩,时间)
我们要进一步分析:如何实现多点、灵活,并在一个描述中指定某个类的某些方法?
也就是说,我们需要这样一个表达式来灵活地描述上述信息。
该表达式表达的内容为:
每个部分有什么要求?
那么我们设计的表达式就会被我们用来决定是否需要增强某个类的某个方法。这个决策过程应该是什么样的?
我们根据您的需求选择是:
AspectJ官网:http://www.gsm-guard.net/aspectj
切入点表达式要匹配的对象是目标方法的方法名。因此,执行表达式显然就是方法的签名。注意,表达式中带[]的部分表示该部分可以省略,各部分之间用空格分隔。可以使用以下符号
示例: