今天开始学习spring中的另一个重要部分:aop,由于aop中涉及到很多相关概念,本文就做一个基础介绍,先让大家认识一下aop。
AOP概念
AOP,也就是面向切面编程。我们都知道java是面向对象的语言,按照这个原则,每个对象都应该只做属于它自己的事(单一职责原则),但在实际开发中,有些场景用面向对象不是很好理解,比如对一个工程的所有方法都添加一个打印日志的功能,这是个很常见的写法,但从面向对象的角度来说,这段代码就不容易理解,它属于侵入式的写法,对于这种场景,提出了aop的概念,打印日志的操作就像一个切面注入所有的方法中,这样子,aop反而成了oop的一种补充。
通过aop的实现,在不改变原先业务逻辑的情况,还可以加入我们需要的横切逻辑,这就是aop带来的好处。
AOP术语
Join point:连接点,也就是我们aop操作发生的地方,可能是一个方法,也可能是一个类的初始化前,这取决我们设置的筛选逻辑;
Pointcut:切入点,当一个连接点被执行的时候,那么他就成为了一个切入点,切入点就是接下来会执行aop逻辑的地方;
Advice:增强,也就是我们要执行的aop的逻辑;
Aspect:切面,切面由切点和增强组成。切面中有连接点的定义,还有横切逻辑的定义。
Introduction:引介,可以理解为一种特殊的增强,通过引介,哪怕这个类没有实现某接口,也可以动态的使它实现该接口。
Target object:也就是被代理的对象
AOP proxy:spring中的aop代理
Weaving:织入,将增强添加到目标类的具体连接点的过程就叫织入。
aop proxy类型
spring中的代理主要有两种方法:
- jdk动态代理.
- cglib动态代理
advice类型:
spring目前提供了五种类型的增强:
Before advice:前置增强,在目标方法执行前实施增强;
After returning advice:返回后增强,在目前方法返回结果后实施增强;
After throwing advice:异常抛出增强,在目标方法抛出异常后实施增强;
After (finally) advice: 后置增强,在目标方法执行后实施增强;
Around advice:环绕增强,在目标方法执行前后实施增强;
AOP使用
和spring中bean的使用一样,我们的aop也是既可以通过注解来实现,同样也可以通过xml配置文件来实现,实现方式不重要,毕竟我们主要是学习其中的实现。
我们用一个简单的场景来看下spring aop的使用;在小区的门口,有一个广播喇叭,每天下午都会开始广播,但是开始时间和播放时间都不是固定的,门卫张大爷就想了个办法,广播开始前,他就通知大家广播要开始了,结束以后再告诉大家今天的广播结束了。
在我们上面这个场景中:
喇叭就是我们需要代理的目标对象
张大爷就是切面,连接点就是喇叭开始广播,广播开始前的通知就是前置通知,广播结束后的通知就是后置通知。
接下来我们用代码来实现下:
喇叭:
package com.ljw.aop;
/**
* @author liu.jiawei
* @create 2019-03-15 00:08
**/
public class Trumpet {
/**
* 广播
*/
public void broadcast(){
System.out.println("广播中。。。");
}
}
张大爷:
package com.ljw.aop;
/**
* @author liu.jiawei
* @create 2019-03-15 00:10
**/
public class Zhangdaye {
/**
*前置通知
*/
public void noticeBeforeBroadcast(){
System.out.println("张大爷友情提醒:广播要开始啦。。。");
}
/**
* 后置通知
*/
public void noticeAfterBroadcast(){
System.out.println("张大爷友情提醒:今天的广播结束啦。。。");
}
}
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="trumpet" class="com.ljw.aop.Trumpet"/>
<bean id="zhangdaye" class="com.ljw.aop.Zhangdaye"/>
<aop:config>
<aop:pointcut id="pc" expression="execution(* com.ljw.aop.Trumpet.broadcast())"></aop:pointcut>
<aop:aspect ref="zhangdaye">
<aop:before method="noticeBeforeBroadcast" pointcut-ref="pc"></aop:before>
<aop:after method="noticeAfterBroadcast" pointcut-ref="pc"></aop:after>
</aop:aspect>
</aop:config>
</beans>
测试类:
package com.ljw.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
* @author liu.jiawei
* @create 2019-03-15 00:15
**/
public class TestBroadcast {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext("//Users/liujiawei/code view/spring/SpringMVCWithOutMaven/web/WEB-INF/broadcast.xml");
Trumpet trumpet = (Trumpet) context.getBean("trumpet");
trumpet.broadcast();
}
}
运行结果:
通过上面这个简单的例子,希望能帮助到大家理解aop的概念。