声明切面类
@Aspect(切面):通常是一个类,里面可以定义切入点和通知
配置切入点和通知
LogAdvice.java
package net.cybclass.sp.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; //能被扫描 @Component //告诉Spring,这是一个切面类,里面可以定义切入点和通知 @Aspect public class LogAdvice { //切入点表达式 @Pointcut("execution(* net.cybclass.sp.servicce.VideoServiceImpl.*(..))") public void aspect(){ } //前置通知 @Before("aspect()") public void beforeLog(JoinPoint joinPoint) { System.out.println("LogAdvice beforeLog 被调用了"); } //后置通知 @Before("aspect()") public void afterLog(JoinPoint joinPoint) { System.out.println("LogAdvice afterLog 被调用了"); } }
开启Spring AOP注解配置
package net.cybclass.sp.aop; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Component; //告诉Spring,这个类可以被扫描 @Component //扫描包 @ComponentScan("net.cybclass") @EnableAspectJAutoProxy //开启了spring对aspect的支持 public class AnnotationConfig { }
VideoService.java
package net.cybclass.sp.servicce; import net.cybclass.sp.domain.Video; public interface VideoService { int save(Video video); Video findById(int id); }
VideoServiceImpl.java
package net.cybclass.sp.servicce; import net.cybclass.sp.domain.Video; import org.springframework.stereotype.Component; //@Component("videoService") //相当于配置bean的id @Component() //相当于配置bean的id public class VideoServiceImpl implements VideoService{ public int save(Video video) { System.out.println("保存Video"); return 0; } public Video findById(int id) { System.out.println("根据id找视频"); return new Video(); } }
演示
环绕通知
package net.cybclass.sp.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; //能被扫描 @Component //告诉Spring,这是一个切面类,里面可以定义切入点和通知 @Aspect public class LogAdvice { //切入点表达式 @Pointcut("execution(* net.cybclass.sp.servicce.VideoServiceImpl.*(..))") public void aspect(){ } //前置通知 @Before("aspect()") public void beforeLog(JoinPoint joinPoint) { System.out.println("LogAdvice beforeLog 被调用了"); } //后置通知 @After("aspect()") public void afterLog(JoinPoint joinPoint) { System.out.println("LogAdvice afterLog 被调用了"); } @Around("aspect()") public void around(JoinPoint joinPoint) throws Throwable { //获取目标类 Object target=joinPoint.getTarget().getClass().getName(); System.out.println("调用者:"+target); Object[] args=joinPoint.getArgs(); System.out.println("参数:"+args[0]); Long start=System.currentTimeMillis(); System.out.println("环绕通知 环绕前==========="); //执行连接点的方法 ((ProceedingJoinPoint)joinPoint).proceed(); Long end=System.currentTimeMillis(); System.out.println("环绕通知 环绕后==========="); System.out.println("调用方法总耗时 time = "+(end-start)+" ms "); } }