AOP是什么 :
AOP面向切面编程他是一种编程思想,是指在程序运行期间,将某段代码动态的切入到指定方法的指定位置,将这种编程方式称为面向切面编程
AOP使用场景 :
- 日志
- 事务
使用AOP的好处是:
我们可以将我们系统的业务逻辑和系统模块进行分离,增大耦合度,方便维护
AOP的底层原理:
AOP代理主要使用的动态代理,动态代理分为两类,
1.jdk的动态代理 通过反射来接受代理类,并且要求被代理的类必须实现一个接口
2.cglib动态代理 是一个代码生成的类库,可以在运行时动态生成某个类的子类,通过继承的方式做动态代理,如果被标记为final则不能使用cglib做动态代理
3.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP;如果目标对象没有实现接口,则采用CGLIB库,Spring会自动在JDK动态代理和CGLIB动态代理之间转换。
了解一下AOP的专业术语
- aspect(切面):通常为一个类(切面类),在里面定义切入点和通知
- Joint point(连接点):程序执行过程中明确的点,一般都是方法的调用
- Pointcut(切入点):切面代码实际要执行的地方
- Advice(增强通知):AOP在特定的切入点上执行增强处 before,after,afterReturning,afterThrowing,around
- Target(目标对象):就是织入通知的目标对象
- weaving(织入):织入是将切面与外部的应用类型或者类连接起来以创建通知对象(adviced object)的过程
增强通知的类型介绍
- Before(前置通知):在目标方法执行之前执行这个方法
- AfterReturning(返回通知):在目标方法正藏返回执行
- AfterThrowing(异常通知):在目标方法抛出异常以后执行
- After(后置通知):在目标方法执行之后执行(完全执行完成)
- Around(环绕通知);在目标方法完成前后做增强处理
* try{
* //@Before
* method.invoke()//目标方法
* //@AfterReturning
* }catch(Exception e){
* //@AfterThrowing
* }finally{
* //@After
* }
切入点表达式
语法结构: @Pointcut(" execution( [权限修改符] [返回值类型] [全类名].[方法名](参数表) 方法申明抛出的异常 ))
举例:@Pointcut("execution(* com.monitoring.controller..*.*(..))")
注:第一个*后面有空格
第一个*表示匹配任意的方法返回值,..(两个点)表示零个或多个,上面的第一个..表示service包及其子包,第二个*表示所有类,第三个*表示所有方法,第二个..表示方法的任意参数个数
如何使用AOP
- 核心容器
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
commons-logging-1.1.3.jar
//注解
spring-aop-4.0.0.RELEASE.jar
//面向切面编程模块
spring-aspects-4.0.0.RELEASE.jar
//增强版面向切面编程
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2.配置
spring文件进行配置
<beans xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" <beans>
<!-- 自动为@aspectJ切面bean创建代理,true表示使用CGLib来创建 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
3.实现
- 首先编写切面类
- 使用@Aspect来表明是切面类 然后使用@Component进行注入切面类
- 在切面类中使用切入点表达式编写切入点
- 编写通知方法
`
@Aspect
@Component
public class LogAop {
// 切点
// @Pointcut("execution(* com.monitoring.controller..*.*(..))")
@Pointcut("@annotation(com.annotations.LogAnnotation)")
private void controllerAspect() {}
//增强
@Around("controllerAspect()")
public Object log(ProceedingJoinPoint pjp )throws Throwable{}