java AOP(面向切面)


一:反射

public class Reflect{

   public static void main(String [] args){

    Class c = Class.forname("包名+类名"); //forname(包的完整路径)

    Object o = c.newInstance(); //这个方法会调用类的无参构造方法,完成对象创建,不过需要保证类中无参构造存在,如果只有有参构造,没有无参构造会报错

   }

二:AOP(面相切面)

(1)表达式

execuption(访问权限 方法返回值 方法声明(方法参数) 异常类型)  //表达式共四个部分,其中访问权限和异常类型可以省略,各部分中间用空格分开

例子1:execuption(public * *(..))  //指定切入点为公共方法

例子2:execuption(* set*(..)) //因为方法返回值和方法声明(方法参数)这两部分是不能省略,所以表达式表示的是任意返回值,以set开头的方法,任意参数

例子3:execuption(* com.baidu.service.*.*(..)) //这个表达式为:任意返回值,com.baidu.service包下的任意类,任意类下的任意方法

例子4:表示多级包一起用

  例如 :com.util.service.impl

                   com.baidu.service.impl

                  com.tengxun.service.impl

execuption(* *..service.*.*(..)) //这样就可以不同的包共用一个表达式了

解析:第一个*表示方法返回值,第二个*表示任意字符, ..表示当前包和子包,service作为基类,service后面的第一个*表示任意包,第二个*表示包中的任意方法

(2)如何在项目中使用

五种通知注解:@Before //前置通知,在目标方法之前执行

                        @AfterReturning //后置通知 在目标方法之后执行

       @Around //环绕通知(常用)目标方法前后都可以执行

                           @AfterThrowing //异常通知(了解)

                          @After //最终通知(了解)

第一步:需要在项目中添加aspectj依赖

第二步:新建一个普通类,在类上加上@Aspectj 注解,用来生命这个类是切面类

第三步:写表达式(前置通知例子)  

@Aspectj

public class AspectjTest{

  //定义切面执行方法,要求:方法无参数,无返回值

 @Before(value = "execuption(public * *.*(..))")  //在定义的方法上添加@Before注解,value = 中写需要表达式,如果方法带参数,只需要写参数的类型,不需要带形参名

  public void myBefore(){

        //里面写需要执行的逻辑代码,比如权限验证,日志记录

         System.out.println("前置通知中的方法执行了");

      }

  }

扩展:后置通知(在目标方法执行之后执行) 使用注解 @AfterReturning

//方法实例

@AfterReturning(valur="execuption(public * *.*(..))" returning="res")

 public void myAfterReturning(Object res){  //需要注意的是:方法中Object 后的形参明可以随便定义,但是必须要和returning中的res值保持一致

  System.out.println("后置通知要执行的代码");

相关