使用Spring进行面向方面编程
2016-08-11 17:18
459 查看
使用Spring进行面向方面编程
1. 在Spring中开始使用AOP
记录方法执行引入依赖
spring-aop
spring-core
spring-beans
spring-context
aspectjweaver
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.1.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.1.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.1.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.1.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency>
创建执行通知的类,实现MethodBeforeAdvice,AfterReturningAdvice接口
public class MethodTimeAop implements MethodBeforeAdvice,AfterReturningAdvice { long time=0; @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { time=System.currentTimeMillis()-time; System.out.println("执行方法"+o1.getClass().getCanonicalName()+"类 "+method.getName()+"耗时 "+time); time=0; } @Override public void before(Method method, Object[] objects, Object o) throws Throwable { time=System.currentTimeMillis(); } }
创建Spring配置文件,配置执行执行通知的Bean 切入点 通知
<context:component-scan base-package="org.pikachu"/> <context:annotation-config></context:annotation-config> <bean class="org.pikachu.MethodTimeAop" id="methodTimeAop"> </bean> <aop:config> <aop:pointcut id="methodTimePointcut" expression="execution(public * *(..))"/> <aop:advisor advice-ref="methodTimeAop" pointcut-ref="methodTimePointcut"/> </aop:config>
创建两个类,分别编写一个方法 使用类级别@Component
在main函数中进行测试
2. 熟悉通知的类型
BeforeAfter Returning
After Throwing
After(Finally)
Around
public class MehtodAop implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice{ @Override public void before(Method method, Object[] objects, Object o) throws Throwable { String methodName=method.getName(); String className=o.getClass().getName(); System.out.println("Before "+className+"类 "+methodName+"方法"); } @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { String methodName=method.getName(); String className=o1.getClass().getName(); System.out.println("After Returning "+className+"类 "+methodName+"方法"); } public void afterThrowing(Method method,Object[] args,Object target,Exception ex){ String methodName=method.getName(); String className=target.getClass().getName(); System.out.println("afterThrowing "+className+"类 "+methodName+"方法"); } public void afterfinally(JoinPoint joinpoint){ String methodName=joinpoint.getSignature().getClass().getCanonicalName(); String className=joinpoint.getTarget().getClass().getCanonicalName(); System.out.println("after finally "+className+"类 "+methodName+"方法"); } public void around(ProceedingJoinPoint joinPoint) throws Throwable { String methodName=joinPoint.getSignature().getName(); String className=joinPoint.getTarget().getClass().getName(); System.out.println("around before "+className+"类 "+methodName+"方法"); joinPoint.proceed(); System.out.println("around after "+className+"类 "+methodName+"方法"); } }
<context:component-scan base-package="org.pikachu"/> <context:annotation-config></context:annotation-config> <bean class="org.pikachu.MehtodAop" id="mehtodAop"> </bean> <aop:config> <aop:pointcut id="aopPointcut" expression="execution(public * *(..))"/> <aop:advisor advice-ref="mehtodAop" pointcut-ref="aopPointcut"/> <aop:aspect ref="mehtodAop"> <aop:after method="afterfinally" pointcut-ref="aopPointcut"/> <aop:around method="around" pointcut-ref="aopPointcut"/> </aop:aspect> </aop:config>
顺序
Beforearound before
after finally
around after
After Returning
3. 定义切入点指示符
within()execution(.*(parameters))
bean(*Service)
@annotation(org.pikachu.MarkerMethodAnnotation)
@within(org.pikachu.MarkerMethodAnnotation)
This(org.pikachu.MarkerMethodAnnotation)
通配符 | 定义 |
---|---|
.. | 匹配方法定义中的任何数量的参数,匹配类定义中任何数量的包 |
+ | 匹配给定类的任何子类 |
* | 匹配任何数量的字符 |
4. 利用注解的强大功能
@Before@PointCut
@After
@AfterReturning
@AfterThrowing
@Aspect
@Around
@DeclareParents
@Component @Aspect public class MethodAop { @Pointcut("execution(public * *(..))") public void anyPublicMethod(){ } @Pointcut("@annotation(org.pikachu.MarkerAnnotation)") public void annotationWithMarkerAnnotation(){ } @Before("anyPublicMethod()") public void before(JoinPoint joinPoint){ String className=joinPoint.getTarget().getClass().getName(); String methodName=joinPoint.getSignature().getName(); System.out.println("@Before "+className+"类 "+methodName+"方法"); } @Before(value = "anyPublicMethod() && args(param)") public void before(JoinPoint joinPoint,String param){ String className=joinPoint.getTarget().getClass().getName(); String methodName=joinPoint.getSignature().getName(); System.out.println("@Before "+className+"类 "+methodName+"方法" +" 带有参数 "+param); } @After("anyPublicMethod() && annotationWithMarkerAnnotation())") public void after(JoinPoint joinPoint){ String className=joinPoint.getTarget().getClass().getName(); String methodName=joinPoint.getSignature().getName(); System.out.println("@After "+className+"类 "+methodName+"方法"+" 带有注解@MarkAnnotation"); } @AfterReturning(value = "anyPublicMethod() ",returning = "returnParam") public void afterReturning(JoinPoint joinPoint, String returnParam){ String className=joinPoint.getTarget().getClass().getName(); String methodName=joinPoint.getSignature().getName(); System.out.println("@AfterReturning "+className+"类 "+methodName+"方法"+" 返回值 "+returnParam); } @AfterReturning("anyPublicMethod()") public void afterReturning(JoinPoint joinPoint){ String className=joinPoint.getTarget().getClass().getName(); String methodName=joinPoint.getSignature().getName(); System.out.println("@AfterReturning "+className+"类 "+methodName+"方法"); } @AfterThrowing(value = "within(org.pikachu.MethodTest)",throwing = < dd66 span class="hljs-string">"t") public void afterThrowing(JoinPoint joinPoint,Throwable t){ String className=joinPoint.getTarget().getClass().getName(); String methodName=joinPoint.getSignature().getName(); System.out.println("@AfterThrowing "+className+"类 "+methodName+"方法"+" 异常"+t.getMessage()); } @Around("anyPublicMethod()") public void around(ProceedingJoinPoint joinPoint) throws Throwable { String className=joinPoint.getTarget().getClass().getName(); String methodName=joinPoint.getSignature().getName(); System.out.println("@Around before "+className+"类 "+methodName+"方法"); joinPoint.proceed(); System.out.println("@Around after "+className+"类 "+methodName+"方法"); } }
@Component @Aspect public class GreekMythologyIntroducer { @DeclareParents(value = "org.pikachu.declareParents.Pegasus+",defaultImpl = Bird.class) public static IBird iBird; }
5. 将ApectJ和Spring融合在一起
使用ApectJ记录方法的执行时间<context:component-scan base-package="org.pikachu"/> <context:annotation-config></context:annotation-config> <aop:aspectj-autoproxy> </aop:aspectj-autoproxy>
6. 使用注解配置Spring AOP
使用@Configuration使用@ComponentScan 配置basePackages
使用@EnableAspectJAutoProxy 启用AspectJ注解
相关文章推荐
- Java集合框架(List, Set, Map, Collections)
- 【JAVA语言程序设计基础篇】--图形-- 一些总结
- SpringMVC与Mybatis集合实现调用存储过程、事务控制
- MyEclipse8.5安装egit无效
- java设计模式——装饰模式(Decorator Pattern)
- java之不死神兔(斐波那契数列)
- JAVA_OPTS参数说明与配置 (Out Of Memofy错误处理)
- Eclipse查看jar的源码和文档
- win10下JDK8的安装与环境配置
- Error: Could not create the Java Virtual Machine
- leetcode-258. Add Digits
- java.lang.ClassNotFoundException: org.codehaus.jackson.JsonProcess******
- springSecurity安全框架配置详解
- 累赘-----解决eclipse中无法导入项目的问题
- Java学习笔记(运算符/Java的算术运算符/赋值运算符/比较运算符/逻辑运算符)
- java 异常捕捉 ( try catch finally ) 你真的掌握了吗?
- 密码学概要--JAVA
- MemoryAnalyzer的使用
- Java Float.isNaN Double.isNaN方法工作原理
- 《深入理解Java集合框架》系列文章