本人在学校学习spring的时候已经接触过spring的面向切面编程,当时我按照书本的方法配置,试图演示面向切面的作用,可惜一直没能成功,后来刚参加工作,需要用到切面记录日志,用了三天的时间终于把切面日志完成。其实spring、springboot的面向切面编程都很简单,只是一直犯了一个错误没能运行成功,因此,这次也是想写此博客,记录一下spring boot切面功能的实现。
首先得先搭建一个spring boot的项目,这里不再详细复述,如果不懂的可以参考sping boot 项目搭建
框架搭建完以后我们需要在pom.xml添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
然后我们就可以去实现切面逻辑,为了方便我们实现一个自定义注解Log类
@Target({ElementType.TYPE,ElementType.METHOD}) // 注解类型, 级别、可以作用于类、接口、方法
@Retention(RetentionPolicy.RUNTIME) //运行时有效
@Inherited
@Documented
public @interface Log {
String value() default "";
}
这样在我们需要记录的类或者方法上添加注解@Log,就能实现aop切点的作用,我们新建一个实体类Eat
@Log
public class Eat{
public void eat(){
System.out.println("准备吃苹果")
}
}
然后我们需要创建一个切面类LogAspect
@Aspect
@Component
public class LogAspect {
static int i=1;
Logger logger = LoggerFactory.getLogger(WebguardApplication.class);
@Pointcut("@annotation(com.iauto.tools.webguard.log.annotation.Log)")
public void serviceAspect() {} //这样就可以使用serviceAspect()替换上面一行切点了
/**
*
* @param joinPoint
*/
@Before("serviceAspect()")//执行方法前
public void doBefore(JoinPoint point) {
System.out.println("吃苹果前要洗手")
}
/**
*
* @param point
* @throws Throwable
*/
@Around("serviceAspect()") //环绕通知
public Object doAround(ProceedingJoinPoint point) {
Object object = null;
try {
object = point.proceed(); //这行很重要,不执行这个方法,程序将无法进入业务方法
System.out.println("正在吃苹果")
}
catch (Throwable e) {
System.out.println(e.getMessage()) //打印错误信息
}
return object;
}
/**
*
* @param ret
*/
@AfterReturning(returning = "ret",pointcut = "serviceAspect()") //后置通知
public void doAfter(Object ret) {
System.out.println("苹果吃完了")
}
//记录错误情况
@AfterThrowing(pointcut="serviceAspect()",throwing = "e")
public void doAfterThrows(JoinPoint point, Exception e) {
System.out.println(e.getMessage()) //打印错误信息
}
}
我们实现一个主类,用来执行Eat类的方法
@SpringBootApplication
public class Main implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(WebguardApplication.class, args);
}
}
//这里调用Eat.eat()
@Override
public void run(ApplicationArguments args) throws Exception {
new Eat().eat();
}
运行结果:
吃苹果前要吸收
准备吃苹果
正在吃苹果
苹果吃完