Spring AOP的注解方式在官网的doc文档里也有详细的说明:http://docs.spring.io/spring/docs/2.0.8/reference/aop.html
还是上篇日志的示例工程,现在换成Annotation注解的方式来配置AOP,工程结构一样的:
AllLogAdvice类代码变成了如下:
package com.aop; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class AllLogAdvice { private Logger logger = Logger.getLogger(AllLogAdvice.class); // @Pointcut("execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))") // @Pointcut("within(com.test.spring.aop.pointcutexp..*)") // @Pointcut("this(com.test.spring.aop.pointcutexp.Intf)") // @Pointcut("target(com.test.spring.aop.pointcutexp.Intf)") // @Pointcut("@within(org.springframework.transaction.annotation.Transactional)") // @Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)") // @Pointcut("args(String)") @Pointcut("execution(* com.service.UserService.add*(..)) || execution(* com.service.UserService.delete*(..))") public void pointcut1() { // 定义一个pointcut,下面用Annotation标注的通知方法可以公用这个pointcut } // 前置通知 // 拦截参数为一个String类型的方法 @Before("pointcut1() && args(temp)") public void myBeforeAdvice(String temp) {// 如果需要知道拦截的方法的信息,也可以需添加JoinPoint参数 String logInfoText = "这是前置通知" + temp; // 将日志信息写入配置的文件中 logger.info(logInfoText); } // 后置通知 // 拦截 返回类型为String 的方法 @AfterReturning(pointcut = "pointcut1()", returning = "result") public void myAfterReturnAdvice(String result) { logger.info("这是后置通知 " + " result: " + result); } // 最终置通知 @After("execution(* com.service.UserService.add*(..))") public void doAfter() { logger.info("这是最终通知"); } // 异常通知 @AfterThrowing(pointcut = "pointcut1()", throwing = "e") public void myThrowingAdvice(JoinPoint jionpoint, Exception e) { // 获取被调用的类名 String targetClassName = jionpoint.getTarget().getClass().getName(); // 获取被调用的方法名 String targetMethodName = jionpoint.getSignature().getName(); // 日志格式字符串 String logInfoText = "异常通知:执行" + targetClassName + "类的" + targetMethodName + "方法时发生异常"; // 将日志信息写入配置的文件中 logger.info(logInfoText); } // 环绕通知 // @Around(value="pointcut1()") @Around("pointcut1()") public Object myAroundAdvice(ProceedingJoinPoint jionpoint) throws Throwable { // 获取被调用的方法名 String targetMethodName = jionpoint.getSignature().getName(); Object o = jionpoint.proceed(); String logInfoText = "这是环绕通知:" + targetMethodName; logger.info(logInfoText); //Object o = jionpoint.proceed();//注意写到这儿的话,环绕通知和其它通知的顺序 return o; } }
代码里加了很多注释说明,注意这儿多了一个最终通知。aop.xml文件的内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <bean id="myUserService" class="com.service.UserService"></bean> <bean id="allLogAdvice" class="com.aop.AllLogAdvice"></bean> <aop:aspectj-autoproxy /> <!-- 如果不声明AllLogAdvice的bean,可以在com.aop下的类加上@Component <context:component-scan base-package="com.aop"/> --> </beans>
注意这里添加了<aop:aspectj-autoproxy />,而且声明了com.aop.AllLogAdvice的bean,如果不声明这个bean的话,在这个类的头上添加@Component,然后通过component-scan扫描也可以。
这儿我把UserService类稍微改了一下:
package com.service; public class UserService implements IUserService { public int addUser(String name, int age) { //省略诸如操作数据库等复杂的逻辑操作 System.out.println("add user "+ name +" successfully"); return 1; } public void deleteUser(String name) { //省略诸如操作数据库等复杂的逻辑操作 System.out.println("deleted one user named " + name); //throw new RuntimeException("这是特意抛出的异常信息!"); } }
addUser方法改成了int型的返回值,deleteUser方法依然是void。
MainTest主测试类代码没有变化:
package com.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.service.IUserService; public class MainTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "aop.xml"); IUserService userService = (IUserService) context .getBean("myUserService"); userService.addUser("ton", 56); userService.deleteUser("ton"); } }
好啦,看看执行结果:
add user ton successfully [INFO ] [14:48:43] com.aop.AllLogAdvice - 这是最终通知 [INFO ] [14:48:43] com.aop.AllLogAdvice - 这是环绕通知:addUser [INFO ] [14:48:43] com.aop.AllLogAdvice - 这是前置通知ton deleted one user named ton [INFO ] [14:48:43] com.aop.AllLogAdvice - 这是后置通知 result: null [INFO ] [14:48:43] com.aop.AllLogAdvice - 这是环绕通知:deleteUser
结果发现,后置通知本来是要拦截返回值是String的方法,addUser确实没有被拦截,但是deleteUser明明是void也被拦截了。
工程代码在附件中。。。
相关推荐
它包括了如`<context:component-scan>`、`<context:annotation-config>`等元素,使得我们可以方便地启用注解驱动的配置和组件扫描,发现并自动装配带有特定注解的类。此外,它还支持消息源、AOP代理、事件监听等特性...
Spring AOP是Spring框架的一部分,它允许我们在不修改源代码的情况下,对应用程序进行横切关注点(如日志、事务管理、性能监控等)的插入。 首先,我们要理解`spring-aop-aroud-demo.zip`这个压缩包中的核心概念: ...
- **AspectJ编译时织入和运行时织入**:AspectJ提供了编译时和类加载时的织入方式,比Spring AOP更强大,可以在编译阶段就处理切面逻辑。 - **AspectJ语法**:包括引入(Introduction)、注解(Annotation)和声明...
在Java编程领域,Spring框架是应用最广泛的轻量级开源框架之一,它提供了一系列强大的功能,包括依赖注入、面向切面编程(AOP)等。本篇将详细讲解Spring中的AOP实现,特别是JDK动态代理的应用。 首先,我们要了解...
在Spring AOP中,我们可以通过注解配置来实现切面编程,从而简化代码并提高可维护性。 首先,我们需要了解Spring AOP中的核心概念: 1. **切面(Aspect)**:切面是关注点的模块化,它包含了横切关注点(如日志)和...
本实例将详细探讨如何通过注解(Annotation)来实现Spring AOP的方法拦截。 一、Spring AOP基础 Spring AOP是Spring框架的一部分,它提供了一种在运行时织入横切关注点(如日志、事务管理等)到目标对象的能力。AOP...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点问题,如日志、事务管理等。在本主题中,我们将深入探讨Spring AOP的注解版,它是基于Java注解的...
- `applicationContext-aop.xml`: 这个XML配置文件很可能包含了Spring AOP的配置,包括切面、通知以及事务管理的设置。例如,我们可以看到使用`<aop:config>`标签来定义切面,`<tx:annotation-driven>`来启用基于...
029-spring-ioc-基于注解方式ioc配置.mp4 030-spring-ioc-扩展周期方法和作用域注解.mp4 031-spring-ioc-di注入注解语法.mp4 032-spring-ioc-属性@Value注解.mp4 033-spring-ioc-注解三层综合案例.mp4 034-...
029-spring-ioc-基于注解方式ioc配置.mp4 030-spring-ioc-扩展周期方法和作用域注解.mp4 031-spring-ioc-di注入注解语法.mp4 032-spring-ioc-属性@Value注解.mp4 033-spring-ioc-注解三层综合案例.mp4 034-...
029-spring-ioc-基于注解方式ioc配置.mp4 030-spring-ioc-扩展周期方法和作用域注解.mp4 031-spring-ioc-di注入注解语法.mp4 032-spring-ioc-属性@Value注解.mp4 033-spring-ioc-注解三层综合案例.mp4 034-...
029-spring-ioc-基于注解方式ioc配置.mp4 030-spring-ioc-扩展周期方法和作用域注解.mp4 031-spring-ioc-di注入注解语法.mp4 032-spring-ioc-属性@Value注解.mp4 033-spring-ioc-注解三层综合案例.mp4 034-...
在本项目"spring-txn-annotation-demo.zip"中,我们主要关注的是如何使用Spring框架的注解来管理事务,这是一个适合初学者学习和研究的示例。该项目基于Spring 5.0.2版本,结合Maven构建工具以及IntelliJ IDEA(一个...
在本资料"Spring_Annotation_AOP"中,我们将深入探讨Spring框架如何利用注解实现AOP,以及其背后的原理和实践应用。 面向切面编程(AOP)是一种编程范式,旨在提高代码的可维护性和可重用性,通过将关注点分离,...
在应用启动时,Spring Boot会自动发现mybatis-spring-boot-starter依赖,并配置好SqlSessionFactory和MapperScannerConfigurer,这样我们无需编写大量配置文件,只需在Java类上添加注解即可。 在多数据源的实现中,...
要启用注解驱动的 AOP,需要在 Spring 配置文件中添加 `<aop:aspectj-autoproxy>` 标签,或者在 Java 配置类中使用 `@EnableAspectJAutoProxy` 注解。 6. **运行环境** 由于这是一个简单的例子,因此运行环境的...
在Spring Boot应用中,我们经常会使用注解来简化配置,提高开发效率。Spring Boot自定义注解配合SPEL(Spring Expression Language)表达式可以让我们实现更为灵活的逻辑控制。本压缩包“spring-boot-annotation-...
本篇文章将深入探讨如何使用Spring的声明式事务,特别是通过Annotation注解方式进行设置。 首先,我们需要理解什么是声明式事务。与编程式事务(即手动编写事务管理代码)不同,声明式事务是通过AOP(面向切面编程...
本篇我们将深入探讨如何使用注解的方式来实现Spring AOP开发。 ### 一、注解基础 在Spring AOP中,主要使用以下几种注解: 1. `@Aspect`:定义一个切面类,切面是AOP的核心,包含通知(advisors)和切点...