Spring AOP学习
一、Spring AOP概念
(1)AOP(Aspect Oriented Programming)是面向切面
编程。
就是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
简单说 就是在不改变方法原代码的基础上,对方法进行功能增强
本质上是生成了一个新的类,叫做代理类
- (2)AOP对程序的扩展方式采用
动态代理
的方式. (JDK动态代
理和Cglib动态代理
两种方式)
二、Spring AOP常用术语
- (1)Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
- (2)Joint point(连接点):表示在程序中明确定义的点,典型的包括
方法调用
,对类成员的访问以及异常处理
程序块的执行等等,它自身还可以嵌套其它 joint point。 - (3)Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
- (4)Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
- (5)Target(目标对象):植入 Advice 的目标对象.。
- (6)Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程
通知方法:
- 前置通知:在我们执行目标方法之前运行(
@Before
) - 后置通知:在我们目标方法运行结束之后 ,不管有没有异常(
@After
) - 返回通知:在我们的目标方法正常返回值后运行(
@AfterReturning
) - 异常通知:在我们的目标方法出现异常后运行(
@AfterThrowing
) - 环绕通知:动态代理, 需要手动执行joinPoint.procced()(其实就是执行我们的目标方法执行之前相当于前置通知, 执行之后就相当于我们后置通知(
@Around
)
三、动态代理
(1)JDK的动态代理
Proxy类的方法
Proxy类的静态方法可以创建代理对象
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
---->三个参数
参数1:ClassLoader loader 类加载器 , 用来加载代理对象
参数2:Class<?>[] interfaces 目标类的字节码对象数组. 因为代理的是接口,需要知道接口中所有的方法
参数3:InvocationHandler h 执行句柄, 代理对象处理的核心逻辑就在该接口中
(2)案例:老总吃饭
老总类
秘书类
TestJdkProxy
public class TestJdkProxy {
public static void main(String[] args) {
//Jdk代理
//ILaoZong
LaoZong laoZong = new LaoZong();
MiShu miShu = new MiShu();
//1 创建一个代理类,创建该类的对象
ClassLoader classLoader = LaoZong.class.getClassLoader();
Class[] interfaces= new Class[]{
ILaoZong.class};
//处理器
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调 laibeijiu()
miShu.laiBeiJiu();
//调 eat()
//laoZong.eat();
//method 被增加的方法
Object returnValue = method.invoke(laoZong,args);
//调 laiGenYan()
miShu.laiGenYan();
return returnValue;
}
};
ILaoZong iLaoZong = (ILaoZong) Proxy.newProxyInstance(classLoader,interfaces,handler);
iLaoZong.eat();
}
}
LaoZong
public class LaoZong implements ILaoZong{
public void eat(){
System.out.println("eat san xia guo");
System.out.println("eat wa wa cai");
}
}
ILaoZong 共同接口
public interface ILaoZong {
void eat();
}
MiShu
public class MiShu {
public void laiBeiJiu(){
System.out.println("laiBeiJiu");
}
public void laiGenYan(){
System.out.println("laiGenYan");
}
}