Spring AOP 之AspectJ注解和XML配置两种实现(Maven构建)
来源:互联网 发布:ogame银河帝国源码 编辑:程序博客网 时间:2024/06/15 08:14
xml配置
1.接口和实现类
public interface UserManager { public String findUserById(int userId);}
@Servicepublic class UserManagerImpl implements UserManager { @Override public String findUserById(int userId) { System.out.println("---------UserManagerImpl.findUserById()--------"); if (userId <= 0) { throw new IllegalArgumentException("该用户不存在!"); } return "张三"; }}
2.单独写一个Advice通知类进行测试
public class XMLAdvice { /** * 在核心业务执行前执行 不能阻止核心业务的调用 */ private void doBefore(JoinPoint joinPoint) { System.out.println("---doBefore().invoke--"); System.out.println(" 此处意在执行核心业务逻辑前,做一些安全性的判断等等"); System.out.println(" 可通过joinPoint来获取所需要的内容"); System.out.println("-----End of doBefore()------"); } /** * 手动控制调用核心业务逻辑,以及调用前和调用后的处理 * <p> * 注意:当核心业务抛异常后 立即退出 转向AfterAdvice * 执行完AfterAdvice 再转向Throwing Advice */ private Object doAround(ProceedingJoinPoint pjp) throws Throwable { System.out.println("-----doAround().invoke-----"); System.out.println(" 此处可以做类似于Before Advice的事情"); //调用核心逻辑 Object retVal = pjp.proceed(); System.out.println(" 此处可以做类似于After Advice的事情"); System.out.println("-----End of doAround()------"); return retVal; } /** * 核心业务逻辑退出后(包括正常执行结束和异常退出),执行此Advice */ private void doAfter(JoinPoint joinPoint) { System.out.println("-----doAfter().invoke-----"); System.out.println(" 此处意在执行核心业务逻辑之后,做一些日志记录操作等等"); System.out.println(" 可通过joinPoint来获取所需要的内容"); System.out.println("-----End of doAfter()------"); } /** * 核心业务逻辑调用正常退出后,不管是否有返回值,正常退出后,均执行此Advice */ private void doReturn(JoinPoint joinPoint) { System.out.println("-----doReturn().invoke-----"); System.out.println(" 此处可以对返回值做进一步处理"); System.out.println(" 可通过joinPoint来获取所需要的内容"); System.out.println("-----End of doReturn()------"); } /** * 核心业务逻辑调用异常退出后,执行此Advice,处理错误信息 */ private void doThrowing(JoinPoint joinPoint, Throwable ex) { System.out.println("-----doThrowing().invoke-----"); System.out.println(" 错误信息:" + ex.getMessage()); System.out.println(" 此处意在执行核心业务逻辑出错时,捕获异常,并可做一些日志记录操作等等"); System.out.println(" 可通过joinPoint来获取所需要的内容"); System.out.println("-----End of doThrowing()------"); }}
3.在Spring配置文件中配置
<bean id="xmlHandler" class="aop.XMLAdvice"/><aop:config> <aop:aspect id="aspect" ref="xmlHandler"> <aop:pointcut id="pointUserMgr" expression="execution(* intergrate.service.*.find*(..))"/> <aop:before method="doBefore" pointcut-ref="pointUserMgr"/> <aop:around method="doAround" pointcut-ref="pointUserMgr"/> <aop:after method="doAfter" pointcut-ref="pointUserMgr"/> <aop:after-returning method="doReturn" pointcut-ref="pointUserMgr"/> <aop:after-throwing method="doThrowing" throwing="ex" pointcut-ref="pointUserMgr"/> </aop:aspect> </aop:config>
4.测试
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:spring-service.xml")public class UserManagerImplTest { @Resource private UserManager userManager; @Test public void test() throws Exception { //正常运行 String user = userManager.findUserById(1); System.out.println("user:" + user); System.out.println("=====华丽丽的分割线======="); //抛异常 try { userManager.findUserById(0); } catch (Exception e) { } }}
输出结果
---doBefore().invoke-- 此处意在执行核心业务逻辑前,做一些安全性的判断等等 可通过joinPoint来获取所需要的内容-----End of doBefore()-----------doAround().invoke----- 此处可以做类似于Before Advice的事情---------UserManagerImpl.findUserById()-------- 此处可以做类似于After Advice的事情-----End of doAround()-----------doAfter().invoke----- 此处意在执行核心业务逻辑之后,做一些日志记录操作等等 可通过joinPoint来获取所需要的内容-----End of doAfter()-----------doReturn().invoke----- 此处可以对返回值做进一步处理 可通过joinPoint来获取所需要的内容-----End of doReturn()------user:张三=====华丽丽的分割线=======---doBefore().invoke-- 此处意在执行核心业务逻辑前,做一些安全性的判断等等 可通过joinPoint来获取所需要的内容-----End of doBefore()-----------doAround().invoke----- 此处可以做类似于Before Advice的事情---------UserManagerImpl.findUserById()-------------doAfter().invoke----- 此处意在执行核心业务逻辑之后,做一些日志记录操作等等 可通过joinPoint来获取所需要的内容-----End of doAfter()-----------doThrowing().invoke----- 错误信息:该用户不存在! 此处意在执行核心业务逻辑出错时,捕获异常,并可做一些日志记录操作等等 可通过joinPoint来获取所需要的内容-----End of doThrowing()------
值得注意的是Around与Before和After的执行顺序。3者的执行顺序取决于在xml中的配置顺序
如果配置顺序是aop:after -> aop:around ->aop:before,那么before和after都会包含在around中。这种情况的产生是由于Around的特殊性,它可以做类似于Before和After的操作。当安全性的判断不通过时,可以阻止核心业务逻辑的调用,这是Before做不到的。
AspectJ注解
接口和实现类
与上面相同
自定义AspceJAdvice
@Aspectpublic class AspceJAdvice { /** * Pointcut * 定义Pointcut,Pointcut的名称是aspectjMethod(),此方法没有返回值和参数 * 该方法就是一个标识 不进行调用 */ @Pointcut("execution(* find*(..))") private void aspectjMethod() { } /** * Before * 在核心业务执行前执行,不能阻止核心业务的调用 */ @Before("aspectjMethod()") public void beforeAdvice(JoinPoint joinPoint) { System.out.println("-----beforeAdvice().invoke-----"); System.out.println(" 此处意在执行核心业务逻辑前,做一些安全性的判断等等"); System.out.println(" 可通过joinPoint来获取所需要的内容"); System.out.println("-----End of beforeAdvice()------"); } /** * After * 核心业务逻辑退出后(包括正常执行结束和异常退出),执行此Advice */ @After("aspectjMethod()") public void afterMethod(JoinPoint joinPoint) { System.out.println("-----afterAdvice().invoke-----"); System.out.println(" 此处意在执行核心业务逻辑之后,做一些日志记录操作等等"); System.out.println(" 可通过joinPoint来获取所需要的内容"); System.out.println("-----End of afterAdvice()------"); } /** * Around * 手动控制调用核心业务逻辑,以及调用前和调用后的处理, * <p> * 注意:当核心业务抛异常后,立即退出,转向AfterAdvice * 执行完AfterAdvice,再转到ThrowingAdvice */ @Around(value = "aspectjMethod()") public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable { System.out.println("-----aroundAdvice().invoke-----"); System.out.println(" 此处可以做类似于Before Advice的事情"); //调用核心逻辑 Object retVal = pjp.proceed(); System.out.println(" 此处可以做类似于After Advice的事情"); System.out.println("-----End of aroundAdvice()------"); return retVal; } /** * AfterReturning * 核心业务逻辑调用正常退出后,不管是否有返回值,正常退出后,均执行此Advice */ @AfterReturning(value = "aspectjMethod()", returning = "retVal") public void afterReturningAdvice(JoinPoint joinPoint, String retVal) { System.out.println("-----afterReturningAdvice().invoke-----"); System.out.println("Return Value: " + retVal); System.out.println(" 此处可以对返回值做进一步处理"); System.out.println(" 可通过joinPoint来获取所需要的内容"); System.out.println("-----End of afterReturningAdvice()------"); } /** * 核心业务逻辑调用异常退出后,执行此Advice,处理错误信息 * <p> * 注意:执行顺序在Around Advice之后 */ @AfterThrowing(value = "aspectjMethod()", throwing = "ex") public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) { System.out.println("-----afterThrowingAdvice().invoke-----"); System.out.println(" 错误信息:" + ex.getMessage()); System.out.println(" 此处意在执行核心业务逻辑出错时,捕获异常,并可做一些日志记录操作等等"); System.out.println(" 可通过joinPoint来获取所需要的内容"); System.out.println("-----End of afterThrowingAdvice()------"); }}
Spring配置文件中配置
<bean id="aspcejHandler" class="aop.AspceJAdvice"/><aop:aspectj-autoproxy/>
测试
同上
输出结果
-----aroundAdvice().invoke----- 此处可以做类似于Before Advice的事情-----beforeAdvice().invoke----- 此处意在执行核心业务逻辑前,做一些安全性的判断等等 可通过joinPoint来获取所需要的内容-----End of beforeAdvice()---------------UserManagerImpl.findUserById()-------- 此处可以做类似于After Advice的事情-----End of aroundAdvice()-----------afterAdvice().invoke----- 此处意在执行核心业务逻辑之后,做一些日志记录操作等等 可通过joinPoint来获取所需要的内容-----End of afterAdvice()-----------afterReturningAdvice().invoke-----Return Value: 张三 此处可以对返回值做进一步处理 可通过joinPoint来获取所需要的内容-----End of afterReturningAdvice()------user:张三=====华丽丽的分割线=======-----aroundAdvice().invoke----- 此处可以做类似于Before Advice的事情-----beforeAdvice().invoke----- 此处意在执行核心业务逻辑前,做一些安全性的判断等等 可通过joinPoint来获取所需要的内容-----End of beforeAdvice()---------------UserManagerImpl.findUserById()-------------afterAdvice().invoke----- 此处意在执行核心业务逻辑之后,做一些日志记录操作等等 可通过joinPoint来获取所需要的内容-----End of afterAdvice()-----------afterThrowingAdvice().invoke----- 错误信息:该用户不存在! 此处意在执行核心业务逻辑出错时,捕获异常,并可做一些日志记录操作等等 可通过joinPoint来获取所需要的内容-----End of afterThrowingAdvice()------
通过测试的发现AroundAdvice、BeforeAdvice、AfterAdvice、ReturningAdvice的执行顺序是根据注解的顺序而定的
XML配置和注解配置优缺点
XML配置优点
- xml 作为可扩展标记语言最大的优势在于开发者能够为软件量身定制适用的标记,使代码更加通俗易懂。
- 利用 xml 配置能使软件更具扩展性。例如 Spring 将 class 间的依赖配置在 xml 中,最大限度地提升应用的可扩展性。
- 具有成熟的验证机制确保程序正确性。利用 Schema 或 DTD 可以对 xml 的正确性进行验证,避免了非法的配置导致应用程序出错。
修改配置而无需变动现有程序。
XML配置缺点
- 需要解析工具或类库的支持。
- 解析 xml 势必会影响应用程序性能,占用系统资源。
- 配置文件过多导致管理变得困难。
- 编译期无法对其配置项的正确性进行验证,或要查错只能在运行期。
- IDE 无法验证配置项的正确性无能为力。
- 查错变得困难。往往配置的一个手误导致莫名其妙的错误。
- 开发人员不得不同时维护代码和配置文件,开发效率变得低下。
- 配置项与代码间存在潜规则。改变了任何一方都有可能影响另外一方。
注解配置优点
- 保存在 class 文件中,降低维护成本。
- 无需工具支持,无需解析。
- 编译期即可验证正确性,查错变得容易。
- 提升开发效率。
注解配置缺点
- 若要对配置项进行修改,不得不修改 Java 文件,重新编译打包应用。
- 配置项编码在 Java 文件中,可扩展性差。
阅读全文
0 0
- Spring AOP 之AspectJ注解和XML配置两种实现(Maven构建)
- Spring AOP AspectJ注解和XML配置两种实现(Maven构建)
- 【Spring aop】Spring aop的XML和注解的两种配置实现
- Spring Aop实例之AspectJ注解配置
- Spring Aop实例之AspectJ注解配置
- Spring AOP Aspectj 注解配置
- spring aop注解和xml两种方式的基础
- Spring框架实现AOP的xml和注解两种方式
- spring系列(二)——AOP的两种实现方式(xml和注解)
- Spring框架学习-深入理解AOP02----AOP简介,AspectJ,AOP基于注解和XML配置(5种通知,切面优先级)
- Spring的AOP分为注解和配置两种方式实现
- Spring-AOP之aspectj注解方式
- spring之基于aspectj注解aop使用
- Spring 之AOP 使用@AspectJ注解方式
- Spring4深入理解AOP02----AOP简介,AspectJ,AOP基于注解和XML配置(5种通知,切面优先级)
- 【spring】AOP xml和注解实现方式
- Spring AOP+AspectJ在XML配置实例
- 实例说明Spring实现AOP的2种方式(注解和XML配置)
- 找到焦点onfocus和失去焦点onblur、以及onchange
- Python生成PASCAL VOC格式的xml标注文件
- 找到一本不错的Linux电子书,附《Linux就该这么学》章节目录。
- 找到一本不错的Linux电子书,附《Linux就该这么学》章节目录
- 创建linux0.11文件系统
- Spring AOP 之AspectJ注解和XML配置两种实现(Maven构建)
- Windows开机自动启动某些软件
- 12-MySQL数据类型:与Java数据类型对应关系
- CodeForces
- Scala学习笔记
- spring boot 连接fastDFS
- C/C++基础知识3
- U3D对于按钮的事件监听
- [DP] [1D1D优化] [FFT] [CDQ分治] [HDU5730] Shell Necklace