00:00
好,前面的部分呢,我们说了一下注解版AOC的内容,那么呢,我们接下来来说注解版的a opoc,也就是面向切面编程,如果对这个a op还不了解的同学可以去我们上硅谷的官网看一下spring a op部分的内容,在这一节呢,我们只做一个场景的简单演示啊,我们着重呢来说A里边的一些核心原理,好,我来写一个新的配置类,我们在这里边来说游戏,那问好我们来说它是一个configuration配置文件,在这里边呢,我们来说AC面向切面编程,也就是它就是指指啊,我们能在程序运行期间动态的将某段代码。
01:00
切入到指定方法、指定位置进行运行的编程方式。要说呢,这就是我们这个A,当然这个A在我们以前学习它的底层,其实就是我们的动态代理,那么呢,我们把这些A的场景我们来写出来,首先第一个我们需要导入咱们这个的模块,导入A模块,而且呢,Spring的A模块也对A做了一些简化操作,哎,我们只需要加上几个核心注解,A就能工作起来。好,我们先来导入A模块在我们文件中。Op的依赖呢,就是我们要打到安斯X保存,保证我们版依赖里边有咱们这个切面包,还有咱们这个S接微软好,那么呢,这是我们第一步先把这个S导入进来。
02:11
主要来spring是来做切面,面向切面编程的,接下来呢,第二步我们来创建一个业务逻辑类,我们把这个场景写出来A。比如呢,我来写创建一个类啊,我们就叫ma q来做一个数学计算器,这里边呢有一个方法in,它咱们这个叫div除法,除法里边呢,我们写两个参数in特接,然后呢,我们把这个I阶进行返回,I除阶我们把这个结果呢进行返回,这是我们的业务逻辑类。好,定义一个业务逻辑类,就是我们这个mass ccul,只不过呢,我们现在想要做的事就是在我们这个mass cancul letter除法运行的运行之前,我们记录一下日志,说哪个方法运行了,用的参数是什么,运行结束了,哎,我们可以来把它的返回值打印一下啊,如果运行出异常了,捕获一下异常信息等,哎,我们现在希望呢,就是在业务逻辑运行的时候,哎将咱们这个日志进行打印,而且呢,在方法运行之前,方法之前包括呢方法运行结束,包括呢方法出现异常等等位置,我们都希望会有打印方法出现异常等等,比如说呢,这是我们哎的需求,那么我们来写了一个业务逻辑类mass calcul。
03:59
我们这儿有一个div方法,如果我们把打印啊都放在这,这是一种耦合的方式,所以说呢,我们不放这,那么呢,我们接下来写一个类,这个类呢,专门来是一个咱们这个日志的切面类,我们就叫log安斯。
04:20
那么我们来写一个方法叫log,这个方法呢,我们希望在目标方法,我们调这个方法来输出一下我们哪个方法运行出发运行。除法运行,然后呢,它用的咱们这个参数,参数列表是,哎,我们希望在这有打印,那么呢,与此同时,如果我们除法结束了,哎,我们调这个方法给他打印除法,哎,结束。然后呢,如果是除法正常返回了,有返回值,我们就叫log个它除法正常返回,正常返回我们希望看到的是咱们这个运行结果,计算结果是多少,把计算结果们打印,包括呢,如果除法出现异常,Log exception,好除法异常,那么我们可以打印一下这个异常信息,异常信息好,这是我们有一个类叫log aspect,我们这个日志切面类,定义一个日志切面类,哎,我们是这个相当于呢,我们这个日志切面类里边的这些方法。
05:58
牵着类,然后的方法的方法需要咱们这个动态感知到咱们这个div运行到哪一步了,感知咱们这个div有种calculator的这个除法运行到哪里了,然后进行执行,运行到哪里,然后执行也要说如果这个除法开始了,我们就调log aspects的啊日志开始记录,如果除法结束了,我们调结束记录,那么这些方法呢,我们就是我们以前说的概念,我们称为啥是通知方法,我们这个类里边有这些通知方法。
06:37
通知方法,而通知方法呢,我们所谓的通知方法,哎有这么几种,一种叫前置通知,一种叫后置通知,还有我们的返回通知,还有我们的异常通知,包括呢,我们有还有一个最强大的通知叫环绕通知,那么这些通知方法是什么意思呢?前置通知哎,我们就类似于我们这里边的log,我们就是他也就说呢,它是希望在目标方法,目标方法也就是我们这个div运行之前运行。
07:21
包括呢,我们这个后置通知,就是我们这个log end啊,我们准备把它作为后置通知,它是在目标方法div运行结束之后运行这个返回通知,哎,我们就是这个log return,我们把它作为返回通知,但是在目标方法就是我们这个div正常返回之后运行,然后呢,我们这个div方法它运行的时候呢,可能会正常,可能会出异常,如果正常返回了,我们来执行,而如果是异常了。
08:04
如果是异常,我们就来调这个log exception来记录异常信息,在目标方法运行出现异常以后,方法我们这个div运行异常,出现异常以后来运行好,然后呢,我们这个环绕通知,我们这儿没写这个环绕通知呢,它其实就是一个动态代理,然后呢,我们直接手动啊推进目标方法运行,就是说呢,我们手动的来调用一下,比如我们哎有一个叫join port,我们这个连接点点proceed。这个呢,我们以前大家也见过,我们如果手手动调用一下咱们这个方法,那么呢,我们这个目标方法就会执行,那执行之前那就是前置通知,执行正常结束那就是返回通知,跟我们以前一样,这个啊环绕通知,这相当于就是一个啊最底层的通知,那么呢,我们就来把这四个通知先写出来,而这四个通知对应的注解,一个呢叫安特北宋一,这个呢,后置通知叫an after,然后返回通知呢,我们叫an after returning,我们正常返回after returning,我们异常通知呢,我们叫after row,而我们的环绕通知我们叫around,这是我们几个通知方法的注解,所以说呢,我接下来。
09:51
第四步,我们给切面内那目标方法啊,标注何时何地运行,也就是标注我们的这些通知注解好,我来到这个切面类,我先来标注上北。
10:16
记住,这个是我们接的,这个可不是我们这个解的好,这个的意思是在目标方法运行之前运行,那么目标方法是什么呢?我们把这个目标方法拿来。哎,我们直接复制一下目标方法的全名就在这儿,然后呢,我们加上访问修饰符返回值类型,这样的话呢,就是来执行int返回值,Div方法两个int参数啊,我们会把它切入进来,然后整个注解T代表切入时机啊,能在目标方法之前切入,它是在目标方法之前切入,但是是哪个切入呢?哪个目标方法呢?我们后边指定的这一串,我们称为切入点表达式,哎,这就是我们以前的这种切入点表达式的写法,哎,指定。
11:13
在哪个方法求,如果我们想来切慢ccul的所有方法,那我们加一个星,包括呢,我们不想区分咱们这个到底是什么参数,我们加双点还是任意多参数任意了一些,好,我们来接下来呢,我再来把这个也写上after啊,我们这个方法的后置通知,后置通知就是方法结束啊,它就会被调用,不管是正常结束还是异常结束,这就是后置通治,无论方法正常结束还是异常结束都调用好,那我们把这个标好了啊,我们还是把这个切入点表达式拿过来,但是你看啊,如果切入点表达式都一样的情况下,你每次复制粘贴也挺麻烦的,能来抽取一下公共的切入点表达式,随便写一个方法,欢迎它咔嚓哎。
12:13
我们随便写一个方法啊,也不用有实现,然后呢,我们给这个方法上加一个point cut注解,这就是我们来抽取公共的切入点表达式,来抽取出来以后呢,如果在本类引用啊,我们本类呢,要用这个切入点表达式。那我们以前的这一串我们就不写了,把这个删掉,哎,我们只需要写这个方法名小括号这就行了,好,所以说呢,本类就这么来写,那如果是哎,外部的类,好,其他的前面,其他的前面引入引用,那我们说我们这个类就叫切面类,如果其他的切面类要引用我们这个,那就在这,哎,就在这儿来写的是这个全名,方法的全名就是我们刚才copy name复制的这个全名,而我们把切入点啊,我们就写在这excution。
13:19
好,我们来要切入到math calculator,我们把这个方法全面复制来。好,加上访问修饰符,哎,以及返回值类型,包括呢,我们方法到底是怎么样?哎,我们切所有方法带两个参数了,那么这个切入点表达式的写法,大家直接参照spring的官方文档就行了,这种写法非常多,哎,我们不在这儿来说它,好,我们这个切入点表达式我们抽取过来了,如果是外部类,你也可以这么来引用,我现在这么来引用没问题,好,那现在呢,用after returning,我们方法正常返回,正常返回呢,我们也是。
14:00
这样好,包括按after死,那么这个方法呢,出现异常好,这样的话呢,我们相当于在切面类里边把每一个方法,哎,把每一个方法在何时何地切入啊,我们都指定了,我们做到第四步,那么基于注解版的A怎么做呢?接下来第五步就是说重要的一步,将咱们这个切面类和目标,也就是说我们这个业务逻辑类,也就说我们这个目标啊,将要被切入到这个目标方法所在的都加入到容器中,比如说我们这个,呃,切面类和将要被切的这个业务逻辑组件啊,我们都要加到咱们这个容器。
15:01
那我就来在这儿来写上两个添加方法,一个呢叫mass can q letter,好,我就叫canalcul,有一个can,好我们把它加在容器中,这是第一个,我们把业务逻辑类加入到容器中,然后呢,我们来第二个,我们再把切面类也加入到容器中,好好往里看,我们这个前面那叫log aspect log aspect好我们把这个前面类return new,一个啊,我这个叫log s100,我们也加在容器中,那如果只是加在容器中,哎,行不行呢?这样还是不。
16:01
行的,我们接下来最重要的一步必须告诉,必须告诉spring哪个类是切面类,比就说呢,这两个类我如果我们都加在业务逻辑啊,把这些啊组件加在容器中,那么怎么没法区别这个是切面还是这个是业务逻辑,那么怎么区别呢?我们只需要给切面类上加一个注解,给切面位上加一个注解,哪个注解呢?我们来到前面类需要有一个注解加N,这个注解呢,代表的是啊,我们当前类是一个切面,告诉spring当前类是一个切面类,而不是一些其他普通的这个类,好,我们把这个写好以后呢,好,我们就加上aspect中形,然后呢,第七。
17:01
我们要把这个a op运行起来,就剩最后一个关键的一步,如果是以前我们基于配置的,我们可能呢,在我们这个B插面中能能写一个来导入A的这个名称空间,然后呢,我们能写一个叫a op a op接auto,哎,也就说按咱们这个切面自动代理,哎也就是说这就是开启基于注解版的这个切面功能,这是开启基于注解版的切面,嗯,但是呢,我们现在又没有这个配置文件啊,我们这个配置文件呢,只是让大家看好,那我们要怎么办呢?哎,同样的们在我们当前的这个配置类中,我们加一个叫able来开启unpe接auto,比如说呢,我们需要给们这个配置为加加一个什么。
18:01
叫enable SP兼auto,也就说呢,启用SP接自动代理,哎,这个就是开启基于注解的A模式,也就说这是最关键的一步,一定把它加上,那么把它加上以后呢,我们来写一个测试方法,我来测一下CTRLC,我们来测一下我们这个切面能不能成功,LP好点进来,好,我们把这个man confident我们取消掉,我们叫man confident a op,好,那这个测的时候呢,好多同学容易犯的一个问题就是呢,哎,他怎么测呢?啊,又一个math canc math canc math can,然后呢,它来调用。
19:01
这个除法他想看那些通知方法是不是被调用了,一除一,哎,随便写啊,如果我们这个通知方,如果我们本方法被调用,我们就打印一下这个本方法会被调mass letter的div div,比方说如果你这么来测,那肯定没有啥功能,我可以看一下走,为什么没功能呢?很简单,这是我们自己随随便便new的对象,而不是容器帮我们管理的这个组件对象。哎,我们massalcul,我们给容器中有放一个mass calcul,只有加在容器中的这些组件才能使用spring提供的这些强大的其他切面等功能。所以说呢,我们这个对象不要自己创建,不要自己创建,要自己创建啊,咱们这个对象我们要使用spring容器中的这个组。
20:01
我们从容器中get b拿到好,我们来运行一下它的这个除法,这样一除一,诶,我们来看。走,诶,大家会看到我们这个除法如果运行打印的是这一个除法运行参数列表,哎,这句话也已经打印了,这是我们的什么呢?就是这个前置通知,哎,我们呢,就给它加一个enter before,好,包括呢,前置通知先执行,接下来呢,是我们目标方法,目标方法执行完以后呢,是后置通知,就说我们这个除法结束了after,那么呢,如果目标方法是正常返回,还会执行这个返回通知,我们这个after returning,这是正常返回,哎,我们就能直到咱们这个返回,同时那么呢,这是我们这个切面的功能,其实就做出来了,做出来的最关键的一步就是我们一定要开启基于注解的A模式,就是这个我们来说在在中。
21:20
未来会有很多的咱们这个叫enable enable叉叉叉功能,它们的作用呢,都是啊,开启我们某一项功能,也就是说来替代我们以前的这些配置,所以说呢,这一块是非常重要的啊,大家注意一下,另外呢,我们这个a op切面功能啊,如果想要拿到这些返回值,以及如果有异常,想拿到这些异常能不能拿呢?也可以,那怎么拿呢?我们比如以这个log start为例,我们这个方法啊,开始方案,开始呢,我们入这个join point,还是我们以前的方式,我们拿到这个方法名,我们不叫除法运行了,我们把这个方法名拿一下,好,我们把这个方法名join point.get有一个呢,叫single,叫获取签名,这个签名就是方法的签名,里边有一个get name,这就是方法名,那么参表。
22:20
啊,我们也能拿得到参数表呢,在这个里边有一个get,就是目标方法运行需要用的这个数表,那为了能打用这个工具list,好,这是我们这个获取到方法的方法以及参数表,那么这个结数也一样,我们就来打印一下方法名,方法名好点,Get single.get那这是方法名,如果是方法正常返回,我们还想拿返回值,返回值要怎么拿呢?好,我们先来写一个value,这个value我们这一块呢,表示引用的切入点,表达式,接下来呢,它有一个东西叫returning returning来指定我们这个参数,谁来封装返回值,所以说呢,我们给参数就随便来写一个object,它来接收所。
23:20
行的返回值,我们说它来接返回值,好,那我们就指定一个result result这个参数最终会把方法的返回值封装,我们把它一打印,哎,这些也能获取,包括如果是异常,哎,同出异辙都是一样的,前面这是切入点表达式,我们写一个异常exception来能接所有异常的,并且来告诉per我们这个参数,这个exception是用来接异常的,一定要说,不然的话你突然冒出来一个exception,也不知道这个exception想要干什么,就是呢,我们来用这个说明它来接异常,那我们现在来运行走。
24:04
哎,现在运行运为结果,我们也能看到参数表,也能看到方法名,哎,也都能看到,我们把最后一个的这个方法名也给它打印出来,来,我们来来加一个join point join point,我们把这个join point呢给它打印出来,第2GET sing nature get name。好,我们可以来看一看,现在呢,这些也都是能拿到的。好,方法名除法正常返回,除法正常返回,诶这个忘了没拿好,我们把这个join port呢复制过来,复制过来join port获取到方法名get name走好这一块呢,一定要注意这个问题,就是这个join po如果要写一定不能写在后边,Join pot必须出现在参数的第一位,否则spring也是无法识别的。好这一块注意,比如说join po这个参数一定。
25:28
Point join point,咱们这个参数一定要出现在参数表的第一位,所以说呢,刚才我们专门把这个放在后边就出现错误了,再来看走好这些呢,就都能获取到,包括如果我们出异常,我们看异常信息它能不能打印呢?好,我们在这测试的时候,我们给他给一个处理异常走哎,这个异常信息我们在这儿没让它打印是吧?好,来打开这一块,我们来把这个切面里边的这个异常我们封装来了,我们在这儿打印一下,走重新来保证这些都运行正确,OK,我们这个异常信息也有我们这些,哎,整个A我们是测试正确的。
26:28
可能前面这些注解啊,大家以前都写过,就是呢,额外一定要注意配置类上加上这个注解开启基于哎,咱们这个aspect接的自动代理,就说基于注解的A模式,特别是咱们写这个A呢啊,看起来步骤好像流程很复杂,但是呢,主要把握咱们这个三步就行了,哪三步呢,第一步就是呢,将业务逻辑组件和切面类都加入到咱们这个容器中,并且呢,要告诉spring,告诉spring哪个是前面位啊,也就是说我们的的这个安四主解,这是第一步,第二步在切面肋上,在切面类上。
27:28
那每个通知方法上标注咱们这个通知注解,通知注解,然后呢,告诉per何时何地运行,当然最主要的是要写好这个切入点表达式,这表达式呢,可以参照官方文档的详细解,接下来第三点,也就是最重要的一点,我们这要开启基于注解的模式,如果是配置文件,那么呢,第三点,那就是把他们这个a op的关系配置出来,开启基于注解注解的咱们这个a op模式,好,所以说呢,也就是最后的这个注解,只要把这三步啊,你做完了,那这个A一定是运行成功的。
我来说两句