[学习小结]Spring_通知的那些事和基于配置文件的方式来配置AOP
2014-08-21 10:53
896 查看
Spring_通知的那些事:
说道Spring,肯定都会想到IOC和AOP,这次就是围绕AOP来讲,同时也不得要说AspectJ。[b]AspectJ的了解:[/b]
代码示例:
准备一个接口:
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); }
准备一个接口的实现类:
import org.springframework.stereotype.Component; @Component("arithmeticCalculator") public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override public int add(int i, int j) { int result = i + j; return result; } @Override public int sub(int i, int j) { int result = i - j; return result; } @Override public int mul(int i, int j) { int result = i * j; return result; } @Override public int div(int i, int j) { int result = i / j; return result; } }
配置文件:applicationContext.xml
配置前别忘记了勾选Namespaces:<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 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-4.0.xsd"> <!-- 配置自动扫描的包 --> <context:component-scan base-package="com.atguigu.spring.aop"></context:component-scan> <!-- 配置自动为匹配 aspectJ 注解的 Java 类生成代理对象 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
首先来看一下环绕通知:
/** * 环绕通知需要携带 ProceedingJoinPoint 类型的参数. * 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法. * 且环绕通知必须有返回值, 返回值即为目标方法的返回值 */ @Around("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))") public Object aroundMethod(ProceedingJoinPoint pjd){ Object result = null; String methodName = pjd.getSignature().getName(); try { //前置通知 System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs())); //执行目标方法 result = pjd.proceed(); //返回通知 System.out.println("The method " + methodName + " ends with " + result); } catch (Throwable e) { //异常通知 System.out.println("The method " + methodName + " occurs exception:" + e); throw new RuntimeException(e); } //后置通知 System.out.println("The method " + methodName + " ends"); return result; }
前置通知,后置通知,异常通知,返回通知
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; /** * 可以使用 @Order 注解指定切面的优先级, 值越小优先级越高 */ @Order(2) @Aspect @Component public class LoggingAspect { /** * 定义一个方法, 用于声明切入点表达式. 一般地, 该方法中再不需要添入其他的代码. * 使用 @Pointcut 来声明切入点表达式. * 后面的其他通知直接使用方法名来引用当前的切入点表达式. */ @Pointcut("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))") public void declareJointPointExpression(){} /** * 在 com.atguigu.spring.aop.ArithmeticCalculator 接口的每一个实现类的每一个方法开始之前执行一段代码 */ @Before("declareJointPointExpression()") public void beforeMethod(JoinPoint joinPoint){ String methodName = joinPoint.getSignature().getName(); Object [] args = joinPoint.getArgs(); System.out.println("The method " + methodName + " begins with " + Arrays.asList(args)); } /** * 在方法执行之后执行的代码. 无论该方法是否出现异常 */ @After("declareJointPointExpression()") public void afterMethod(JoinPoint joinPoint){ String methodName = joinPoint.getSignature().getName(); System.out.println("The method " + methodName + " ends"); } /** * 在方法法正常结束受执行的代码 * 返回通知是可以访问到方法的返回值的! */ @AfterReturning(value="declareJointPointExpression()", returning="result") public void afterReturning(JoinPoint joinPoint, Object result){ String methodName = joinPoint.getSignature().getName(); System.out.println("The method " + methodName + " ends with " + result); } /** * 在目标方法出现异常时会执行的代码. * 可以访问到异常对象; 且可以指定在出现特定异常时在执行通知代码 */ @AfterThrowing(value="declareJointPointExpression()", throwing="e") public void afterThrowing(JoinPoint joinPoint, Exception e){ String methodName = joinPoint.getSignature().getName(); System.out.println("The method " + methodName + " occurs excetion:" + e); } }
测试用例:
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator"); System.out.println(arithmeticCalculator.getClass().getName()); int result = arithmeticCalculator.add(1, 2); System.out.println("result:" + result); result = arithmeticCalculator.div(1000, 10); System.out.println("result:" + result); }
测试结果:
1.没有出现异常的情况
com.sun.proxy.$Proxy12 -->validate:[1, 2] The method add begins with [1, 2] The method add ends The method add ends with 3 result:3 -->validate:[1000, 10] The method div begins with [1000, 10] The method div ends The method div ends with 100 result:100
2.出现异常的情况:
com.sun.proxy.$Proxy12 -->validate:[1, 2] The method add begins with [1, 2] The method add ends The method add ends with 3 result:3 -->validate:[1000, 0] The method div begins with [1000, 0] The method div ends The method div occurs excetion:java.lang.ArithmeticException: / by zero
基于配置文件的方式来配置AOP
了解概述:
代码示例:
与上面所述的一样需要接口和一个接口实现类(但这次只有实现类稍微改动一点),取消了注释public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override public int add(int i, int j) { int result = i + j; return result; } @Override public int sub(int i, int j) { int result = i - j; return result; } @Override public int mul(int i, int j) { int result = i * j; return result; } @Override public int div(int i, int j) { int result = i / j; return result; } }
配置文件:applicationContext-xml.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <!-- 配置 bean --> <bean id="arithmeticCalculator" class="com.atguigu.spring.aop.xml.ArithmeticCalculatorImpl"></bean> <!-- 配置切面的 bean. --> <bean id="loggingAspect" class="com.atguigu.spring.aop.xml.LoggingAspect"></bean> <bean id="vlidationAspect" class="com.atguigu.spring.aop.xml.VlidationAspect"></bean> <!-- 配置 AOP --> <aop:config> <!-- 配置切点表达式 --> <aop:pointcut expression="execution(* com.atguigu.spring.aop.xml.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-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/> <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/> <!-- <aop:around method="aroundMethod" pointcut-ref="pointcut"/> --> </aop:aspect> <aop:aspect ref="vlidationAspect" order="1"> <aop:before method="validateArgs" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans>
测试用例与测试结果与上面一样
相关文章推荐
- Spring4学习笔记-AOP(基于配置文件的方式)
- Spring4学习笔记-AOP(基于配置文件的方式)
- 20.Spring学习笔记_基于配置文件的方式来配置 AOP(by尚硅谷_佟刚)
- spring学习笔记(22)----基于配置文件的方式来配置AOP
- spring学习(七)—AOP通过配置文件方式实现
- 8 -- 深入使用Spring -- 4...6 AOP代理:基于注解的XML配置文件的管理方式
- Spring中的AOP(六)——基于XML配置文件方式的AOP
- 【学习】Spring 的 AOP :基于Annotation 的“零配置”方式
- 8.4.6: Spring的AOP---基于XML配置文件的管理方式
- Spring4学习笔记-Spring4整合Struts2(基于配置文件的方式)
- Spring4学习笔记-Spring4整合Struts2(基于配置文件的方式)
- Spring中的AOP(七)——基于XML配置文件方式的AOP
- 【学习】Spring 的 AOP :基于Annotation 的“零配置”方式
- Spring基于配置文件的方式来配置AOP
- Spring中的AOP(六)——基于XML配置文件方式的AOP
- Spring_22_基于配置文件的方式来配置 AOP
- spring之aop编程——基于注解、xml配置文件方式
- Spring笔记5-基于配置文件的方式配置AOP
- Spring学习-22:Spring的AOP:基于AspectJ的XML配置方式开发
- Spring4学习笔记-声明式事务(基于配置文件的方式)