Spring 框架AOP
来源:互联网 发布:小米笔记本安装centos 编辑:程序博客网 时间:2024/06/05 10:55
AspectJ:Java 社区里最完整最流行的 AOP 框架.
要在 Spring 中声明 AspectJ 切面, 只需要在 IOC 容器中将切面声明为 Bean 实例. 当在 Spring IOC 容器中初始化 AspectJ 切面之后, Spring IOC 容器就会为那些与 AspectJ 切面相匹配的 Bean 创建代理.
在 AspectJ 注解中, 切面只是一个带有 @Aspect 注解的 Java 类.
通知是标注有某种注解的简单的 Java 方法.
AspectJ 支持 5 种类型的通知注解:
- @Before: 前置通知, 在方法执行之前执行
- @After: 后置通知, 在方法执行之后执行
- @AfterRunning: 返回通知, 在方法返回结果之后执行
- @AfterThrowing: 异常通知, 在方法抛出异常之后
- @Around: 环绕通知, 围绕着方法执行
例子(加减乘除计算)
需要引入aspectJ相关的jar包
maven配置
<dependency> <groupId>aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.5.4</version></dependency><dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.0.RELEASE</version></dependency><dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version></dependency>
首先我们这里使用注解的方式进行说明。
spring-aop.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="com.spring.aop.helloworld"></context:component-scan> <!-- 使 AspectJ 的注解起作用 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>
ArithmeticCalculator.java
package com.spring.aop.helloworld;public interface ArithmeticCalculator { int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j);}
ArithmeticCalculatorImpl.java
package com.spring.aop.helloworld;import org.springframework.stereotype.Component;@Component("arithmeticCalculator")public class ArithmeticCalculatorImpl implements ArithmeticCalculator { public int add(int i, int j) { int result = i + j; return result; } public int sub(int i, int j) { int result = i - j; return result; } public int mul(int i, int j) { int result = i * j; return result; } public int div(int i, int j) { int result = i / j; return result; }}
LoggingAspect.java
package com.spring.aop.helloworld;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;/** * 在同一个连接点上应用不止一个切面时, 除非明确指定, 否则它们的优先级是不确定的. * 切面的优先级可以通过实现 Ordered 接口或利用 @Order 注解指定. * 实现 Ordered 接口, getOrder() 方法的返回值越小, 优先级越高. * 若使用 @Order 注解, 序号出现在注解中 * @author cye * */@Order(2)@Aspect@Componentpublic class LoggingAspect { /** * 用于声明切入点表达式,一般该方法中不需要添加其他代码 * 使用@Pointcut来声明切入点表达式 * 后面其他通知直接使用方法名来引用当前的切入点表达式 * 第一个 * 代表任意修饰符及任意返回值. 第二个 * 代表任意方法. .. 匹配任意数量的参数. */ @Pointcut("execution(* int com.spring.aop.helloworld.ArithmeticCalculator.*(..))") public void declareJoinPointExpression() {} /** * 前置通知 * 在方法执行之前执行 * @param joinPoint */ @Before("declareJoinPointExpression()") public void beforeMethod(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("The method " + methodName + " begins with " + Arrays.asList(joinPoint.getArgs())); } /** * 后置通知 * 在方法执行之后执行,无论方法是否出现异常 * @param joinPoint */ @After("declareJoinPointExpression()") public void afterMethod(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("The method " + methodName + " ends with " + Arrays.asList(joinPoint.getArgs())); } /** * 返回通知 * 在方法正常执行之后执行 * 可以访问到方法的返回值 */ @AfterReturning(value="declareJoinPointExpression()", returning="result") public void afterReturningMethod(JoinPoint joinPoint, Object result) { String methodName = joinPoint.getSignature().getName(); System.out.println("The method " + methodName + " afterReturning with " + Arrays.asList(joinPoint.getArgs()) + ", result is " + result); } /** * 异常通知 * 在目标方法出现异常时执行 * 可以访问到异常对象,且可以指定在出现特定异常时再执行 * @param joinPoint * @param e */ @AfterThrowing(value="execution(public int com.spring.aop.helloworld.ArithmeticCalculator.*(..))", throwing="e") public void afterThrowingMethod(JoinPoint joinPoint, ArithmeticException e) { String methodName = joinPoint.getSignature().getName(); System.out.println("The method " + methodName + " occurs exception " + e); } /** * 环绕通知 * 需要带有ProceedingJoinPoint类型的参数,可以决定是否有执行目标方法 * ProceedingJoinPoint . 它是 JoinPoint 的子接口, 允许控制何时执行, 是否执行连接点. * 且环绕通知必须有返回值,返回值即为目标方法的返回值 * @param joinPoint */ @Around(value="execution(public int com.spring.aop.helloworld.ArithmeticCalculator.*(..))") public Object aroundMethod(ProceedingJoinPoint pjp) { String methodName = pjp.getSignature().getName(); Object result = null; try { //前置通知 System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjp.getArgs())); //执行方法 result = pjp.proceed(); //返回通知, 可以访问到方法的返回值 System.out.println("The method " + methodName + " returns with " + Arrays.asList(pjp.getArgs())); } catch (Throwable e) { //异常通知, 可以访问到方法出现的异常 System.out.println("The method occurs exception:" + e); throw new RuntimeException(e); } //后置通知. 因为方法可以能会出异常, 所以访问不到方法的返回值 System.out.println("The method " + methodName + " ends with " + Arrays.asList(pjp.getArgs())); return result; }}
ValidateAspect.java
package com.spring.aop.helloworld;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;/** * * @author cye * */@Order(1)@Aspect@Componentpublic class ValidateAspect { /** * 前置通知 * 在方法执行之前执行 * @param joinPoint */ @Before("LoggingAspect.declareJoinPointExpression()") public void validateMethod(JoinPoint joinPoint) { System.out.println("The validateMethod method "); } }
Main.java
package com.spring.aop.helloworld;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-aop.xml"); ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator"); int result = arithmeticCalculator.add(11, 12); System.out.println("result:" + result); result = arithmeticCalculator.div(21, 3); System.out.println("result:" + result); }}
注解方式
下面我们只把xml配置文件给出,具体类参考上面的。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 配置bean --> <bean id="arithmeticCalculator" class="com.spring.aop.test.ArithmeticCalculatorImpl"></bean> <!-- 配置切面的bean --> <bean id="loggingAspect" class="com.spring.aop.test.LoggingAspect"></bean> <bean id="validateAspect" class="com.spring.aop.test.ValidateAspect"></bean> <!-- 配置AOP --> <aop:config> <!-- 配置切面表达式 --> <aop:pointcut expression="execution(* com.spring.aop.test.ArithmeticCalculator.*(int, int))" id="pointcut"/> <!-- 配置切面及通知 --> <aop:aspect ref="loggingAspect" order="2"> <aop:before method="beforeMethod" pointcut-ref="pointcut"/> <aop:after method="afterMethod" pointcut-ref="pointcut"/> <aop:after-returning method="afterReturningMethod" pointcut-ref="pointcut" returning="result"/> <aop:after-throwing method="afterThrowingMethod" pointcut-ref="pointcut" throwing="e"/> <aop:around method="aroundMethod" pointcut-ref="pointcut"/> </aop:aspect> <aop:aspect ref="validateAspect" order="1"> <aop:before method="validateMethod" pointcut-ref="pointcut"/> </aop:aspect> </aop:config></beans>
0 0
- Spring AOP框架
- Spring AOP框架
- Spring AOP框架
- Spring AOP框架
- Spring AOP框架
- Spring AOP框架
- Spring框架:AOP详解
- Spring AOP框架使用
- 【spring框架】AOP介绍
- Spring框架中的aop
- spring框架_06 AOP
- spring框架--AOP
- Spring AOP框架
- spring框架之AOP
- Spring框架AOP
- Spring框架 AOP(三)
- Spring 框架AOP
- Spring框架-AOP细节
- 1001_北大oj题目理解学习
- Java的类型转换问题
- php支付宝接口的开发
- Android性能测试
- hyperledger fabric 结构分析(三)
- Spring 框架AOP
- SQL Server:知识点(1)
- 动态规划-排成一条线的纸牌博弈问题
- jQuery的deferred对象使用详解——实现ajax同步请求数据
- sql server 清除某个数据库所有数据
- 第一行代码笔记,第七章-----探究内容提供者
- tcp_keepalive的设置
- 眼睁睁看着乙方把项目作死是一种什么感受(项目作死10大方法)
- AVAudioPlayer播放本地音频