SpringAop切面
SpringAOP简介
面向切面编程(Aspect Oriented Programming)提供了另一种角度来思考程序的结构,通过这种方式弥补面向对象编程(Object Oriented Programming)的不足。除了类以外,AOP提供了切面,切面对关注点进行模块化,例如横切多个类型和对象的事务管理(这些关注点术语通常称作横切(crosscutting)关注点)。Spring AOP是Spring的一个重要组件,但是Spring IOC并不依赖于Spring AOP,这意味着你可以自由选择是否使用AOP,AOP提供了强大的中间件解决方案,这使得Spring IOC更加完善。我们可以通过AOP来实现日志监听,事务管理,权限控制等等。
通知(Advice)的类型:
-
前置通知(Before advice):在某个连接点(Joinpoint)之前执行的通知,但这个通知不能阻止连接点的执行(除非它抛出一个异常).
-
返回后通知(After returning advice):在某个连接点(Joinpoint)正常完成后执行的通知。例如,一个方法没有抛出任何异常正常返回.
-
抛出异常后通知(After throwing advice):在方法抛出异常后执行的通知.
-
后置通知(After(finally)advice):当某个连接点(Joinpoint)退出的时候执行的通知(不论是正常返回还是发生异常退出).
-
环绕通知(Around advice):包围一个连接点(Joinpoint)的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行.
-
@EnableAspectJAutoProxy注解:
该注解作用开启AOP模式. -
@Aspect注解:
该注解作用声明切面类. -
@Pointcut注解:
该注解作用为公共的切入点表达式. -
@Before注解:
该注解作用(前置通知)指定在目标方法执行前切入. -
@After注解:
该注解作用(后置通知)指定目标方法执行后切入. -
@AfterReturning注解:
该注解作用(返回通知)正常情况下才执行. -
@AfterThrowing注解:
该注解作用(异常通知)异常信息.
代码实践:
public class BookDao { //Aop切面目标类
public int math(int a,int b) {
System.out.println("AOP目标方法..");
return a/b;
}
}
@Aspect //声明切面类
public class LogAspcets {
/**
* 抽取公共的切入点表达式
*/
@Pointcut("execution(public int springcode.dao.BookDao.*(..))")
public void pointCut(){}
/** 前置通知
* 指定在目标方法执行前切入:
* public int springcode.dao.BookDao.*(..) *表示所有方法
* public int springcode.dao.BookDao.math(int,int) 指定目标切入点
*
* JoinPoint 获取目标方法的签名及参数 注意:JoinPoint参数必须在最前面
*/
@Before(value = "pointCut()")
public void methodBefore(JoinPoint joinPoint) {
Object[] params = joinPoint.getArgs();
System.out.println("目标方法名:"+joinPoint.getSignature().getName()+" 参数 "+ Arrays.toString(params)+" 前置通知...");
}
/**
* 后置通知 目标方法执行后切入
*/
@After(value = "execution(public int springcode.dao.BookDao.*(..))")
public void methodAfter(JoinPoint joinPoint) {
System.out.println("目标方法名:"+joinPoint.getSignature().getName()+" 后置通知...");
}
/**
* 返回通知 (正常情况下才执行) returning 返回结果
*/
@AfterReturning(value = "pointCut()",returning = "result")
public void methodReturn(JoinPoint joinPoint,Object result) {
System.out.println(joinPoint.getSignature().getName()+" 返回通知..."+result);
}
/**
* 异常通知 throwing 异常信息
*/
@AfterThrowing(value = "pointCut()",throwing = "exception")
public void methodException(JoinPoint joinPoint,Exception exception) {
System.out.println(joinPoint.getSignature().getName()+" 异常通知...{"+exception+"}");
}
}
@EnableAspectJAutoProxy //开启AOP模式
@Configuration //配置类 组件注册
public class MainConfigOfAop {
@Bean
public BookDao bookDao() {
return new BookDao(); // 目标类
}
@Bean
public LogAspcets logAspcets() {
return new LogAspcets(); //切面类
}
}
public class AppOfAop {
public static void main(String[] args) { //app应用
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfAop.class);
BookDao bean = context.getBean(BookDao.class);
bean.math(1,1);
}
}