Spring AOP源码分析--代理方式的选择 (2)

然后在LoginController#login方法里我们就可以把日志打印耗时时间的代码删掉了。

1@RestController
2@Slf4j
3public class LoginController {
4    @Autowired
5    LoginService loginService;
6    @RequestMapping("/login/{id}")
7    public Map<String,Object> login(@PathVariable("id") Integer id){
8        Map<String,Object> result = new HashMap<>();
9        result.put("status","0");
10        result.put("msg" , "失败");
11        if (loginService.login(id)) {
12            result.put("status","1");
13            result.put("msg" , "成功");
14        }
15        return result;
16    }
17}

再比如,LoginController里若是还有别的方法,也一样可以应用到。
使用Spring AOP的控制台日志:

Spring AOP源码分析--代理方式的选择

Spring AOP的原理

以上就是Spring AOP的一个应用场景。那Spring AOP的原理是什么呢,用的什么技术呢?
其实就是反射+动态代理。代理用的就是JDK动态代理或cglib,那么Spring AOP什么时候用JDK动态代理什么时候用cglib?默认使用哪种?

源码分析

那么我们就通过源码来看一下吧。首先我们将启动类改一下,方便我们对源码debug。

启动类:

1@ComponentScan("com.walking.springaopsb.*")
2@EnableAspectJAutoProxy
3public class SpringaopSbApplication {
4    public static void main(String[] args) {
5        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringaopSbApplication.class);
6        LoginController loginController = (LoginController) applicationContext.getBean("loginController");
7        loginController.login(123);
8    }
9}

我们修改了一下启动类,把断点打在第6行,启动,往下走一步,看loginController这个变量。

我们发现是cglib方式产生的代理类,说明从IoC容器里拿到的是代理类,到底是初始化IoC容器时生成的还是获取时产生的呢?我们也跟随源码来看一下吧。

Spring AOP源码分析--代理方式的选择

要知道的是,我们现在要看的是第5行还是第6行生成的代理类。先看第6 行的getBean吧,进入这个方法org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.String)。

Spring AOP源码分析--代理方式的选择

然后我们只看有return的地方,在进入这个getBean(org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String))。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsswww.html