/** * @Service和@Aspect 第一个注解是使得TimeMonitor受Spring托管并实例化。@Aspect就是使得这个类具有AOP功能(你可以这样理解)两个注解缺一不可 eg: */ @Service @Aspect public class TimeMonitor { //当UserServiceImpl.sayHello方法执行的时候执行此拦截器 @Around("execution(* me.laiyijie.demo.service.UserServiceImpl.sayHello(..))") public void monitorAround(ProceedingJoinPoint pjp) throws Throwable { System.out.println("method start time:" + System.currentTimeMillis()); Object re = pjp.proceed(); System.out.println("method end time:" + System.currentTimeMillis()); } }
_--------------------------------------------------------------------------------------------------------------------------------------------------
/** * @Around(“execution(* me.laiyijie.demo.service.UserServiceImpl.sayHello(..))”) @Around表示包围一个函数,也就是可以在函数执行前做一些事情,也可以在函数执行后做一些事情 execution(* me.laiyijie.demo.service.UserServiceImpl.sayHello(..)) 这个比较好理解,就是使用表达式的方式指定了要对哪个函数进行包围! Spring AOP 开启需要的配置: pom.xml增加依赖(因为要用到AOP还需要不同的JAR包) root-context.xml中增加切面相关配置 */
root-context.xml::: (1) <?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/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.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <context:component-scan base-package="me.laiyijie.demo"></context:component-scan> </beans> xmlns:aop="http://www.springframework.org/schema/aop" 代表加入命名空间 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 使用1中引入的aop命名空间开起自动代理(自动代理具体含义后续慢慢解释,简单的理解就是AOP的实现是依靠自动代理实现的)
pom.xml:::: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>me.laiyijie</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> </dependencies> </project>一个简单的例子:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * ErrorCode: * 定义一个注解 ,错误异常的注解() */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface ErrorException { int code() default 0;//参数 }
/** * ErrorExceptionAspect: * * @author yangzhenlong * @since 2016/7/21 */ @Component @Aspect public class ErrorExceptionAspect { //@Before("execution(* com.sarkuya.service..*.*(..))") @Pointcut(value = "@annotation(com.mlxs.mvc.anno.ErrorException)") private void pointcut() { } @Around(value = "pointcut() && @annotation(errorExecption)") public Object around(ProceedingJoinPoint point, ErrorException errorExecption){ System.out.println("---->around"); //注解参数 System.out.println("注解参数:"+ errorExecption.code()); //当前拦截的类和方法: Class clazz = point.getTarget().getClass(); Method method = ((MethodSignature) point.getSignature()).getMethod(); String codeName = clazz.getSimpleName()+"_"+method.getName(); System.out.println("query param---->"+codeName); //方法返回结果 Object result = null; Object args = Arrays.asList(point.getArgs()); try { //执行方法(可以在方法前后添加前置和后置通知) result = point.proceed(); //校验结果 result = validateResult(result); } catch (Throwable e) { //记录日志 System.out.println(codeName + "()方法异常:" + e); //打印堆栈信息 e.printStackTrace(); //设置返回信息 result = "结果:抛了异常了。。-----------------------"+e.getMessage()+",原因:"+e.getCause(); } //返回通知 return result; }
/** * 方法执行后 * @param joinPoint * @param result */ @AfterReturning(value = "pointcut() && @annotation(errorExecption)", returning = "result") public Object afterReturning(JoinPoint joinPoint, ErrorException errorExecption, Object result){ System.out.println("---->afterReturning"); String methodName = joinPoint.getSignature().getName(); System.out.println("The method " + methodName + " return with " + result); if(result instanceof Boolean){ if(!((Boolean) result)){ result = "error----result is false"; } }else{ if(result == null){ result = "error----result is null"; } } return result; }一个测试:
/** * _Test: * * @author yangzhenlong * @since 2016/7/21 */ @Component("test") public class _Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring/applicationContext.xml"); _Test obj = (_Test) context.getBean("test"); System.out.println("==========>"+obj.test()); //System.out.println("==========>"+obj.test2()); } @ErrorException(code = 100) public Object test(){ System.out.println("---test---"); int a = 10/0; return 20; } @ErrorException(code = 22) public Object test2(){ System.out.println("---test2---"); //int a = 10/0; return false; } }结果:
---->around 注解参数:100 query param---->_Test_test ---test--- _Test_test()方法异常:java.lang.ArithmeticException: / by zero ---->afterReturning The method test return with 结果:抛了异常了。。-----------------------/ by zero,原因:null ==========>结果:抛了异常了。。-----------------------/ by zero,原因:null java.lang.ArithmeticException: / by zero at com.mlxs.mvc.anno._Test.test(_Test.java:28) at com.mlxs.mvc.anno._Test$$FastClassBySpringCGLIB$$cc5ae48c.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85) at com.mlxs.mvc.anno.ErrorExceptionAspect.around(ErrorExceptionAspect.java:44) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610) at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168) at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168) at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) at com.mlxs.mvc.anno._Test$$EnhancerBySpringCGLIB$$cbf2effd.test(<generated>) at com.mlxs.mvc.anno._Test.main(_Test.java:21) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)