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("后置通知要执行的代码");