20|AutoProxyCreator:如何自动添加动态代理?
问题的引出
- 深入了解
- 翻译
- 解释
- 总结
自动代理创建动态代理技术是一种解决AOP配置问题的创新方法。通过BeanPostProcessor自动创建代理,利用Bean的名称匹配规则自动生成代理,实现对每一个符合规则的Bean进行动态代理的工作。这种技术大大简化了AOP配置,提高了系统的可维护性和扩展性。文章介绍了如何修改getBean方法以应用BeanPostProcessor进行后期处理,对满足规则的Bean进行包装,改头换面成为一个Factory Bean。通过配置文件和代码示例展示了如何使用BeanNameAutoProxyCreator和Advisor来自动创建动态代理,并通过测试验证了其效果。这种基于JDK的AOP方案对于理解AOP原理很有帮助,并展示了IoC容器的强大之处。总的来说,这篇文章为读者提供了一种简单而有效的动态代理创建方法,为理解AOP原理和提高系统可维护性提供了有益的参考。
《手把手带你写一个 MiniSpring》,新⼈⾸单¥59
全部留言(9)
- 最新
- 精选
- 马儿置顶这节课的代码能够做到不需要在beans.xml中额外专门配置来生成代理对象,已经接近spring的雏形了。但是按照之前的代码是跑不起来的,需要对之前的BeanPostProcessor的逻辑修改一下,应该是老师之前讲漏了的部分。主要工作在修改AbstractAutowireCapableBeanFactory类将属性中的beanPostProcessors改为面向接口的列表,其次是修改ClassPathXmlApplicationContext#registerBeanPostProcessors让其可以在配置文件中读到注册的BeanPostProcessors并注册到容器中。最后将我们之前用到的AutowiredAnnotationBeanPostProcessor注册到容器中管理就能够自动发现了。 代码修改可以参考:https://github.com/horseLk/mini-spring/commit/7186afebeaf30d622d79b4111970945abca97701
作者回复: github上每一节的代码都是可运行的。文稿是写重点,会有漏掉细节。感谢你的补充。
2023-04-26归属地:四川 - peter问题放在第20课,但问题是关于第19课的: Q1:Join Point和Pointcut的区别是什么?两个看起来是一回事啊。 Q2:流程方面,Interceptor先拦截,拦截以后再进行增强操作。换一种说法,先是Interceptor工作,然后是Join Point、Pointcut、advice这些登场,对吗? Q3:19课的总结部分,是这样说的:“Advisor:通知者,它实现了 Advice”。19课的留言解答有这样一句话“advisor则是一个管理类,它包了一个advice,还能寻找到符合条件的方法名进行增强”。 留言的解释很不错,但总结部分,“实现了 Advice”,个人感觉这个措辞不是很合理啊,怎么是“实现”?这个词容易让人理解为接口与实现类的关系。
作者回复: Peter总是很用心细致。 Join point跟Pointcut不是一回事,它是指在类中的位置,如是方法上?是构造器上?是属性上?pointcut是条件,如哪些符合条件的方法上加上增强。 流程你得理一下源代码,这些概念之间并没有流程。 口头讲课确实有一些随意,不那么精确,”实现”一词呢,因为advisor里面包了一个advice,就那么说了,不是代码意义上的“实现”。形象地说,advice是饭(真正的业务增强逻辑),advisor是碗筷(装饭给人吃的工具),人不能直接用嘴巴啃饭,要用一个工具把饭吃到嘴里。
2023-04-27归属地:北京5 - __@Wong补充一个点,这里需要保证AutowiredAnnotationBeanPostProcessor和BeanNameAutoProxyCreator两个BeanPostProcessor的优先级,AutowiredAnnotationBeanPostProcessor要在之前哦,在xml文件里面AutowiredAnnotationBeanPostProcessor的bean要放前面。
作者回复: 是
2023-06-24归属地:广东3 - Geek_320730可以定义一个注解@Transaction并实现一个MethodMatcher,根据有没有这个注解来判断方法是否匹配,匹配的话,在方法执行前,手动开启事务,方法结束后,手动提交事务,有异常的话回滚事务。那事务方法调用事务方法的时候不知道会不会报错。。。 另外遇到Bean可以一直嵌套代理的问题,比如上一章手动配置的action,本身就是一个ProxyFactoryBean了,但是他的名字依然符合本章的action*的匹配规则,这样就又加了一层代理,注入的时候就会失败。需要在获取类的时候判断一下类型递归返回,或者在bean匹配规则的时候做一下类型判断,如果本身是个ProxyFactoryBean了,就不做操作返回。
作者回复: 你这个bean嵌套代理的补充很好。
2023-04-26归属地:北京1 - __@Wong将原有的bean替换成代理后的bean那里,如果遇到循环引用会有问题吧, 引用的还是旧的bean。
作者回复: 不会有问题的。因为getBean()也改写了: AbstractBeanFactory的getBean(): //beanpostprocessor //step 1 : postProcessBeforeInitialization singleton = applyBeanPostProcessorsBeforeInitialization(singleton, beanName); //这一步将bean改头换面成proxyfactorybean
2023-06-20归属地:广东2 - __Alucard完结撒花,谢谢指导
作者回复: 恭喜,多谢。
2023-05-29归属地:浙江 - __Alucard动态代理失效的根本原因是@Autowired注解解析的时候,取到的spring bean还是没代理的对象; 我的临时解决方案是 在BeanNameAutoProxyCreator的postProcessBeforeInitialization手动把创建后的动态代理对象注入进spring ioc中, beanFactory.registerBean(beanName,proxyFactoryBean); 但是这样会导致BeanFactory又对外暴露了注册bean的接口,void registerBean(String beanName, Object obj);明显不合适,这个有没有更好的办法
作者回复: 你讲的问题讲到点上了。我只能说Spring目前的方案就是挺合适的方案,我自己想不出别的合适的办法。
2023-05-29归属地:浙江2 - 浩仔是程序员老师你好,怎么github上面这块framework这个包下面有部分代码是重复的呢?建议可以来个代码结构的总结
作者回复: 我检查一下,多谢提醒。
2023-05-02归属地:广东 - 天敌老师,关于使用 Proxy.newProxyInstance 生成的对象在进行 xml 中 ref 的属性绑定过程中,由于生成的代理对象并没有继承被代理对象的类,导致进行赋值时 IllegalArgumentException: argument type mismatch 这个问题,应该如何解决呢?2023-07-23归属地:四川