19 | Spring框架:IoC和AOP是扩展的核心
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
Spring框架的IoC(控制反转)和AOP(面向切面编程)是其核心扩展,分别实现了对象解耦和扩展,以及松耦合、高内聚的精髓。本文通过案例深入剖析IoC和AOP相关的坑,帮助读者理解Spring框架中的核心技术。文章讨论了单例的Bean如何注入Prototype的Bean,指出了忽略类的生命周期可能导致内存泄漏或线程安全问题。修复方式包括使用代理方式注入和考虑Bean的顺序或优先级。这些内容对读者理解Spring框架的复杂性和灵活性具有重要意义。 文章还介绍了AOP实现的监控组件和事务失效的关系,以及通过AOP实现监控组件可能存在的其他坑。通过定义自定义注解Metrics和实现切面MetricsAspect,文章展示了如何实现对标记了@RestController注解的Web控制器的自动切入,以及如何为Service中的方法标记@Metrics注解实现自动监控。最后,通过简单的Controller、Service和Repository的测试,展示了MetricsAspect的功能,包括记录方法的入参和出参日志、方法耗时,以及异常处理。 通过深入讨论IoC和AOP的相关技术细节,以及实际案例的分析和测试,本文帮助读者全面了解Spring框架的核心技术和灵活性,以及如何利用AOP实现监控组件和解决事务失效的问题。文章内容涵盖了Spring框架的关键特性,为读者提供了宝贵的实践经验和解决问题的思路。
《Java 业务开发常见错误 100 例》,新⼈⾸单¥59
全部留言(23)
- 最新
- 精选
- Darren置顶一、注解区别 @Autowired 1、@Autowired是spring自带的注解,通过‘AutowiredAnnotationBeanPostProcessor’ 类实现的依赖注入; 2、@Autowired是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Qualifier; 3、@Autowired有个属性为required,可以配置为false,如果配置为false之后,当没有找到相应bean的时候,系统不会抛错; 4、@Autowired可以作用在变量、setter方法、构造函数上。 @Inject 1、@Inject是JSR330 (Dependency Injection for Java)中的规范,需要导入javax.inject.Inject;实现注入。 2、@Inject是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named; 3、@Inject可以作用在变量、setter方法、构造函数上。 @Resource 1、@Resource是JSR250规范的实现,需要导入javax.annotation实现注入。 2、@Resource是根据名称进行自动装配的,一般会指定一个name属性 3、@Resource可以作用在变量、setter方法上。 总结: 1、@Autowired是spring自带的,@Inject是JSR330规范实现的,@Resource是JSR250规范实现的,需要导入不同的包 2、@Autowired、@Inject用法基本一样,不同的是@Autowired有一个request属性 3、@Autowired、@Inject是默认按照类型匹配的,@Resource是按照名称匹配的 4、@Autowired如果需要按照名称匹配需要和@Qualifier一起使用,@Inject和@Name一起使用 二:循环依赖: 直观解决方法时通过set方法去处理,背后的原理其实是缓存。 主要解决方式:使用三级缓存 singletonObjects: 一级缓存, Cache of singleton objects: bean name --> bean instance earlySingletonObjects: 二级缓存, Cache of early singleton objects: bean name --> bean instance 提前曝光的BEAN缓存 singletonFactories: 三级缓存, Cache of singleton factories: bean name --> ObjectFactory
作者回复: 👍🏻👍🏻👍🏻👍🏻👍🏻👍🏻👍🏻👍🏻👍🏻👍🏻👍🏻
2020-04-267106 - norman@Resource 和 @Autowired @Inject 三者区别: 1 @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。 2 @Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualifier。这个注释是Spring特有的。 3 @Inject是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named
作者回复: 👍🏻,也可以参考 https://stackoverflow.com/questions/20450902/inject-and-resource-and-autowired-annotations 这里的回复
2020-04-258 - 左琪这里的代理类不是单例么,还是说会在增强逻辑里不断创建被代理类?
作者回复: 代理类会来判断是否需要创建新的对象
2020-04-267 - Demon.Lee连接点: 程序执行过程中能够应用通知的所有点;通知(增强): 即切面的工作,定义了What以及When;切点定义了Where,通知被应用的具体位置(哪些连接点) ----Spring实战(第4版)
作者回复: 不错
2020-04-254 - 龙行秀“架构师一开始定义了这么一个 SayService 抽象类,其中维护了一个类型是 ArrayList 的字段 data,用于保存方法处理的中间数据。每次调用 say 方法都会往 data 加入新数据,可以认为 SayService 是有状态,如果 SayService 是单例的话必然会 OOM” -----为什么单例就会OOM,多例就不会呢?没看懂
作者回复: 容器维护了这个单例,回收不了
2020-09-0133 - Joker老师,请教一下,那个sayservice里的data有啥用,那个单例是为了一种重复使用data对吧,那换成每次都生成一个新的bean,那个data还有效果吗。。
作者回复: 只是为了模拟SayService是有状态
2020-04-253 - 小学生老师,您好,您讲 的切面执行顺序好像不对啊,我的执行顺序和你说的不一致! [10:34:11.367] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.a.TestAspectWithOrder10:31 ] - TestAspectWithOrder10 @Around before [10:34:11.377] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.a.TestAspectWithOrder10:21 ] - TestAspectWithOrder10 @Before [10:34:11.377] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.a.TestAspectWithOrder20:31 ] - TestAspectWithOrder20 @Around before [10:34:11.378] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.a.TestAspectWithOrder20:21 ] - TestAspectWithOrder20 @Before [10:34:11.379] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.aopmetrics.MetricsAspect:79 ] - 【入参日志】调用 【class org.geekbang.time.commonmistakes.springpart1.aopmetrics.TestController】【public void org.geekbang.time.commonmistakes.springpart1.aopmetrics.TestController.test()】【http://localhost:45678/test】 的参数是:【[]】 [10:34:11.379] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.aopmetrics.MetricsAspect:88 ] - 【成功打点】调用 【class org.geekbang.time.commonmistakes.springpart1.aopmetrics.TestController】【public void org.geekbang.time.commonmistakes.springpart1.aopmetrics.TestController.test()】【http://localhost:45678/test】 成功,耗时:0 ms [10:34:11.379] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.aopmetrics.MetricsAspect:107 ] - 【出参日志】调用 【class org.geekbang.time.commonmistakes.springpart1.aopmetrics.TestController】【public void org.geekbang.time.commonmistakes.springpart1.aopmetrics.TestController.test()】【http://localhost:45678/test】 的返回是:【null】 [10:34:11.380] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.a.TestAspectWithOrder20:26 ] - TestAspectWithOrder20 @After [10:34:11.380] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.a.TestAspectWithOrder20:33 ] - TestAspectWithOrder20 @Around after [10:34:11.380] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.a.TestAspectWithOrder10:26 ] - TestAspectWithOrder10 @After [10:34:11.380] [http-nio-45678-exec-4] [INFO ] [o.g.t.c.s.a.TestAspectWithOrder10:33 ] - TestAspectWithOrder10 @Around after
作者回复: 哪里不对?
2020-10-1631 - track6688老师,请教一个问题,我使用这个注解,@Order(Ordered.HIGHEST_PRECEDENCE),使用@AfterThrowing这个时,报No MethodInvocation found: Check that an AOP invocation is in progress, and that the ExposeInvocationInterceptor is upfront in the interceptor chain. Specifically, note that advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor!,怎么处理呢?
作者回复: 意思是ExposeInvocationInterceptor需要在前面执行,最新的ExposeInvocationInterceptor已经是PriorityOrdered了,你是不是老版本的Spring?把自己的类优先级调低点
2020-06-121 - 看不到de颜色感觉Spring Intercepter的执行顺序和Servlet Filter的执行过程是一样的,一个递归调用栈。 有个疑问想请老师解答一下。采用创建内部类的方式获取默认注解配置,这样不会每调用一次就会在元空间中生成一个c的Class信息吗?
作者回复: 这不会,会编译为 final class MetricsAspect$1c { MetricsAspect$1c(MetricsAspect this$0) { this.this$0 = this$0; } }
2020-05-161 - David Mo@sevice 的坑踩过,代理类一开始不行白,后来说动态创建就懂了。当时是用一个类似工厂类解决的
作者回复: 好吧
2020-04-301