【英雄】:SpringAOP(面向切面编程)
英雄介绍:
AOP(Aspect Oriented Programming):是一种面向切面的编程范式,是一种编程思想,旨在通过分离横切关注点,提高模块化,可以跨越对象关注点。
英雄定位:权限管理、异常处理、操作日志、事务控制。
主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
被动:AOP术语
引入(Introduction):允许我们向现有的类添加方法和属性。
目标对象(Target Object):通过反射的方式调用可增强目标类的业务逻辑。
代理(Proxy):一个类被AOP织入增强后就产出了一个结果类,它是融合了原类和增强逻辑的代理类,根据不同的代理方式。代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以我们可以采用调用原类相同的方式调用代理类
织入(Weaving):把切面应用到目标对象来创建新的代理对象的过程。
切面(Aspect):是通知和切入点的结合,在SpringAOP中,它会将切面所定义的横切逻辑织入界面所指定的连接点中。
切点(Pointcut):相当于查询条件,找到对应的的连接点,切点和连接点不是一对一的关系。
连接点(JoinPoint)程序执行到某个特定位置(如某个方向调用前、调用后、方法抛出异常后),切点由两个信息确定:第一是用方法表示的程序执行点,第二是用相对点表示的方位。
通知(Advice):是织入目标类连接点上的一段程序代码,在Spring中,增强除用于描述一段程序代码外,还拥有另一个和连接点相关的信息,那便是执行点的方法,大致有前置增强、后置增强、返回后增强、抛异常时增强和包围型增强。
技能一:日志配置
先导入AOP的依赖
<!-- Spring AOP的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SystemLog {
String name() default "";
}
简单的配置一下,详细的配置可以百度自己搜,后续有时间的话我会补充的。
import com.linx.one.myspringboot.annotation.SystemLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
//定义切面
@Aspect
@Component
public class SystemLogAop {
//定义切入点
@Pointcut("@annotation(com.linx.one.myspringboot.annotation.SystemLog)")
public void SystemLog(){
}
//前置通知
@Before("SystemLog()")
public void Before(JoinPoint joinPoint){
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
SystemLog log = method.getAnnotation(SystemLog.class);
String name = log.name();
System.out.println("开始执行方法:"+name);
}
//后置通知
@After("SystemLog()")
public void After(JoinPoint joinPoint){
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
SystemLog log = method.getAnnotation(SystemLog.class);
String name = log.name();
System.out.println(name+"执行结束.");
}
}
测试调用一下
import com.linx.one.myspringboot.annotation.SystemLog;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@RequestMapping("/hello")
@ResponseBody
@SystemLog(name="hello方法")
public String hello(){
return "Hello World";
}
}