论论坛坛网网站站建建设设,江阴网站设计,做外贸是用什么网站做,唐山如何做百度的网站建设AOP
AOP全称是Aspect Oriented Programming 即面向切面编程#xff0c;是对一类统一事务的集中处理 例如#xff0c;我们的网页许多地方都需要进行登陆验证#xff0c;这时就需要在很多地方添加重复的验证代码#xff0c;而AOP可以集中配置需要登陆验证的地方#xff0c;…AOP
AOP全称是Aspect Oriented Programming 即面向切面编程是对一类统一事务的集中处理 例如我们的网页许多地方都需要进行登陆验证这时就需要在很多地方添加重复的验证代码而AOP可以集中配置需要登陆验证的地方就可以简化我们的代码
除此以外还可以实现
统一日志的记录统一方法执行的时间记录统一返回格式的设置统一异常的处理事务的开启和提交
springAOP
就像IoC是思想而DI是实现SpringAOP也是对AOP这种思想的实现
基本组成
切面用来处理问题的一个类包含切点和通知的相关方法切点用来设置拦截的规则通知程序拦截后进行的具体操作连接点触发AOP相关规则的点
其中对于通知还有下面几种不同的分类
前置通知 使用Before注解在目标方法执行前执行后置通知使用After注解在目标方法返回或抛出异常后执行返回通知使用AfterRetruning注解在目标方法返回后执行异常通知使用AfterThrowing注解在目标方法抛出异常后执行环绕通知使用Around注解在包裹的方法执行前后执行后执行
也就是说page123是需要验证是否登陆的页面也就是连接点 验证是否登陆的这个方法就是切点 处理用户登陆问题是通知 而整个验证用户登陆的这个行为称为切面
实现
首先在程序中加入SpringAOP的相关依赖
!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-bo
ot-starter-aop --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId
/dependency在程序中专门建一个类用来存储切面
Aspect
Component
public class 切面方法名{Poiontcut(execution(修饰符 返回类型 包名.类名.方法名(参数) 异常))public void 切点方法名(){}
}其中Aspect注解代表此类是切面 而Component注解使该类在运行时启动
这里的切点方法并没有具体的实现只是用来为通知方法标明执行的是那个切点
而Pointcut注解后面的表达式则是标明拦截的规则
并且表达式中还支持通配符
*匹配任意字符只匹配一个元素…匹配任意字符匹配多个元素匹配指定类及其子类
也就是说
修饰符
例子表达public匹配所有公共方法*匹配所有方法
返回值不能省略
例子表达String匹配所有返回String的方法*匹配所有方法
包名
例子表达com.example.demo匹配com.exaple.demo这个包com.*.demo匹配前面是com结尾是demo的包com.demo…匹配com下面的所有子包
类名
例子表达User匹配User类User*匹配以User开头的类*匹配所有类
方法名不能省略
例子表达getUser匹配getUser这个方法*getUser匹配以getUser结尾的方法*匹配所有方法
参数
例子表达()匹配没有参数的方法(int, float)匹配一个int一个float参数的方法(…)匹配任意类型的参数
例如 定义一个匹配com.example.demo.controller包下UserController的任意方法
Component //随框架启动而启动
Aspect //切面类
public class UserAspect {/*** 定义切点*/Pointcut(execution(* com.example.demo.controller.UserController.*(..)))public void pointcut(){}
}实现通知
前置通知
/*** 前置通知*/
Before(pointcut())
public void beforeAdvice(){System.out.println(执行前置通知);
}后置通知
/*** 后置通知*/
After(pointcut())
public void afterAdvice(){System.out.println(执行后置通知);
} 环绕通知
/*** 环绕通知*/
Around(pointcut())
public Object aroundAdvice(ProceedingJoinPoint joinPoint){System.out.println(进入环绕通知);Object object null;try{//执行拦截方法object joinPoint.proceed();} catch (Throwable e) {e.printStackTrace();}System.out.println(结束环绕通知);return object;
}返回通知
AfterReturning(pointcut())
public void returnAdvice(){System.out.println(执行返回通知);
}异常通知
AfterThrowing(pointcut())
public void throwAdvice(){System.out.println(执行抛出异常通知);
}把UserController类定义出来验证一下这些通知是否执行
RequestMapping(/user)
RestController
public class UserController {RequestMapping(/hi)public String sayHi(String name){System.out.println(执行sayHi方法);return hi name;}RequestMapping(/hello)public String sayHello(){System.out.println(执行sayHello方法);return hello world;}
}在访问127.0.0.1:8080/user/hi页面时程序台就会打印如下信息
实现原理
springAOP只支持方法级别的拦截这是因为其基于动态代理实现 其中分别用JDK Proxy实现接口的类生成代理类和CGLIB没实现接口的类生产代理类
把切面连接到目标对象的相关位置连接点的行为叫织入
其中一般在目标对象的这几个时期织入
编译器类加载期代码运行期SpringAOP实现方式