Spring
【黑马程序员2022新版SSM框架教程_Spring+SpringMVC+Maven高级+SpringBoot+MyBatisPlus企业实用开发技术】
13 AOP 工作流程
13.1 AOP 工作流程
由于AOP是基于Spring容器管理的bean做的增强,所以整个工作过程需要从Spring加载bean说起:
13.1.1 流程1:Spring 容器启动
- 容器启动就需要去加载bean,哪些类需要被加载呢?
- 需要被增强的类,如:BookServiceImpl
- 通知类,如:MyAdvice
- 注意此时bean对象还没有创建成功
13.1.2 流程2:读取所有切面配置中的切入点
上面这个例子中有两个切入点的配置,但是第一个ptx()并没有被使用,所以不会被读取。
13.1.3 流程3:初始化bean
判定bean对应的类中的方法是否匹配到任意切入点
- 注意第1步在容器启动的时候,bean对象还没有被创建成功。
- 要被实例化bean对象的类中的方法和切入点进行匹配
13.1.4 流程4:获取bean执行方法
- 获取的bean是原始对象时,调用方法并执行,完成操作
- 获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作
13.1.5 验证容器中是否为代理对象
为了验证IOC容器中创建的对象和刚才所说的结论是否一致,首先先把结论理出来:
- 如果目标对象中的方法会被增强,那么容器中将存入的是目标对象的代理对象
- 如果目标对象中的方法不被增强,那么容器中将存入的是目标对象本身。
【验证思路】
- 要执行的方法,不被定义的切入点包含,即不要增强,打印当前类的getClass()方法
- 要执行的方法,被定义的切入点包含,即要增强,打印出当前类的getClass()方法
- 观察两次打印的结果
① 修改App类,获取类的类型
package com.dingjiaxiong;
import com.dingjiaxiong.config.SpringConfig;
import com.dingjiaxiong.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = context.getBean(BookDao.class);
System.out.println(bookDao);
System.out.println(bookDao.getClass());
}
}
② 修改MyAdvice类,不增强
因为定义的切入点中,被修改成update1 ,所以BookDao中的update方法在执行的时候,就不会被增强,所以容器中的对象应该是目标对象本身。
③ 运行程序
④ 修改MyAdvice类,增强
因为定义的切入点中,被修改成update ,所以BookDao中的update方法在执行的时候,就会被增强,所以容器中的对象应该是目标对象的代理对象
⑤ 运行程序
这样就得到了结论的验证。
注意:不能直接打印对象,从上面两次结果中可以看出,直接打印对象走的是对象的toString方法,不管是不是代理对象打印的结果都是一样的,原因是内部对toString方法进行了重写。
|