• 马儿
    置顶
    2023-04-26 来自四川
    这节课的代码能够做到不需要在beans.xml中额外专门配置来生成代理对象,已经接近spring的雏形了。但是按照之前的代码是跑不起来的,需要对之前的BeanPostProcessor的逻辑修改一下,应该是老师之前讲漏了的部分。主要工作在修改AbstractAutowireCapableBeanFactory类将属性中的beanPostProcessors改为面向接口的列表,其次是修改ClassPathXmlApplicationContext#registerBeanPostProcessors让其可以在配置文件中读到注册的BeanPostProcessors并注册到容器中。最后将我们之前用到的AutowiredAnnotationBeanPostProcessor注册到容器中管理就能够自动发现了。 代码修改可以参考:https://github.com/horseLk/mini-spring/commit/7186afebeaf30d622d79b4111970945abca97701

    作者回复: github上每一节的代码都是可运行的。文稿是写重点,会有漏掉细节。感谢你的补充。

    
    
  • peter
    2023-04-27 来自北京
    问题放在第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是碗筷(装饭给人吃的工具),人不能直接用嘴巴啃饭,要用一个工具把饭吃到嘴里。

    
    4
  • Geek_320730
    2023-04-26 来自北京
    可以定义一个注解@Transaction并实现一个MethodMatcher,根据有没有这个注解来判断方法是否匹配,匹配的话,在方法执行前,手动开启事务,方法结束后,手动提交事务,有异常的话回滚事务。那事务方法调用事务方法的时候不知道会不会报错。。。 另外遇到Bean可以一直嵌套代理的问题,比如上一章手动配置的action,本身就是一个ProxyFactoryBean了,但是他的名字依然符合本章的action*的匹配规则,这样就又加了一层代理,注入的时候就会失败。需要在获取类的时候判断一下类型递归返回,或者在bean匹配规则的时候做一下类型判断,如果本身是个ProxyFactoryBean了,就不做操作返回。

    作者回复: 你这个bean嵌套代理的补充很好。

    
    1
  • __@Wong
    2023-06-24 来自广东
    补充一个点,这里需要保证AutowiredAnnotationBeanPostProcessor和BeanNameAutoProxyCreator两个BeanPostProcessor的优先级,AutowiredAnnotationBeanPostProcessor要在之前哦,在xml文件里面AutowiredAnnotationBeanPostProcessor的bean要放前面。

    作者回复: 是

    
    
  • __@Wong
    2023-06-20 来自广东
    将原有的bean替换成代理后的bean那里,如果遇到循环引用会有问题吧, 引用的还是旧的bean。

    作者回复: 不会有问题的。因为getBean()也改写了: AbstractBeanFactory的getBean(): //beanpostprocessor //step 1 : postProcessBeforeInitialization singleton = applyBeanPostProcessorsBeforeInitialization(singleton, beanName); //这一步将bean改头换面成proxyfactorybean

    共 2 条评论
    
  • __Alucard
    2023-05-29 来自浙江
    完结撒花,谢谢指导

    作者回复: 恭喜,多谢。

    
    
  • __Alucard
    2023-05-29 来自浙江
    动态代理失效的根本原因是@Autowired注解解析的时候,取到的spring bean还是没代理的对象; 我的临时解决方案是 在BeanNameAutoProxyCreator的postProcessBeforeInitialization手动把创建后的动态代理对象注入进spring ioc中, beanFactory.registerBean(beanName,proxyFactoryBean); 但是这样会导致BeanFactory又对外暴露了注册bean的接口,void registerBean(String beanName, Object obj);明显不合适,这个有没有更好的办法

    作者回复: 你讲的问题讲到点上了。我只能说Spring目前的方案就是挺合适的方案,我自己想不出别的合适的办法。

    共 2 条评论
    
  • 浩仔是程序员
    2023-05-02 来自广东
    老师你好,怎么github上面这块framework这个包下面有部分代码是重复的呢?建议可以来个代码结构的总结

    作者回复: 我检查一下,多谢提醒。

    
    
  • 天敌
    2023-07-23 来自四川
    老师,关于使用 Proxy.newProxyInstance 生成的对象在进行 xml 中 ref 的属性绑定过程中,由于生成的代理对象并没有继承被代理对象的类,导致进行赋值时 IllegalArgumentException: argument type mismatch 这个问题,应该如何解决呢?
    
    