• null
    2019-06-22
    #笔记#
    Glossory

    FooConfig.java:父上下文(parent application context)。
    applicationContext.xml:子上下文(child application context)。

    FooConfig.java 中定义两个 testBean,分别为 testBeanX(foo) 和 testBeanY(foo)。
    applicationContext.xml 定义了一个 testBeanX(bar)。

    委托机制:在自己的 context 中找不到 bean,会委托父 context 查找该 bean。

    ----------

    代码解释:
    fooContext.getBean("testBeanX"),在父上下文查找 testBeanX,命中直接返回 testBeanX(foo)。
    barContext.getBean("testBeanX"),在子上下文查找 testBeanX,命中直接返回 testBeanX(bar)。
    barContext.getBean("testBeanY"),在子上下文查找 testBeanY,未命中;委托父上下文查找,命中,返回 testBeanY(foo)。

    ----------

    场景一:
    父上下文开启 @EnableAspectJAutoProxy 的支持
    子上下文未开启 <aop: aspectj-autoproxy />
    切面 fooAspect 在 FooConfig.java 定义(父上下文增强)

    输出结果:
    testBeanX(foo) 和 testBeanY(foo) 均被增强。
    testBeanX(bar) 未被增强。

    结论:
    在父上下文开启了增强,父的 bean 均被增强,而子的 bean 未被增强。

    ----------
     
    场景二:
    父上下文开启 @EnableAspectJAutoProxy 的支持
    子上下文开启 <aop: aspectj-autoproxy />
    切面 fooAspect 在 applicationContext.xml 定义(子上下文增加)

    输出结果:
    testBeanX(foo) 和 testBeanY(foo) 未被增强。
    testBeanX(bar) 被增强。

    结论:
    在子上下文开启增强,父的 bean 未被增强,子的 bean 被增强。

    ----------

    根据场景一和场景二的结果,有结论:“各个 context 相互独立,每个 context 的 aop 增强只对本 context 的 bean 生效”。如果想将切面配置成通用的,对父和子上下文的 bean 均支持增强,则:
    1. 切面 fooAspect 定义在父上下文。
    2. 父上下文和子上下文,均要开启 aop 的增加,即 @EnableAspectJAutoProxy 或<aop: aspectj-autoproxy /> 的支持。
    展开
    
     53
  • shaohsiung
    2019-03-16
    一个spring应用可以存在多个web上下文,但是只有一个root上下文,这个例子中的fooctx和barctx都是applicationcontext,并将fooctx作为barctx的父容器是为了演示容器的层次关系,这样理解对吗老师?

    作者回复: 上下文可以有很多个,这个是我们自己决定的。我可以编程方式来控制。你说的没错,我这里只是为了演示上下文继承的一些坑。

    
     8
  • 码农Kevin亮
    2019-03-14
    老师我没听太明白,spring mvc 单独搞个ServletWebApplicationContext来管理servlet的bean的意义是什么?反过来问就是,假如都用RootWebApplicationContext来管理,会有什么问题?另外我也没听明白WebApplicationContext与ApplicationContext的区别
    
     8
  • $hell
    2019-07-18
    子容器可以感知父容器(有引用),父容器无法感知子容器

    [Aop支持]--[Aspect信息]--[同侧]:
    parentContext [关闭] Aop 支持----subContext [开启] Aop 支持并[托管] Aspect : 仅注册在子容器中的bean增强;
    parentContext [开启] Aop 支持----subContext [开启] Aop 支持并[托管] Aspect : 仅注册在子容器中的bean增强;因为父容器感知不到子容器中的 Aspect信息
    parentContext [开启] Aop 支持并[托管] Aspect--subContext [关闭] Aop 支持 : 仅注册在父容器中的bean增强,从子容器拿到的父容器bean是属于父容器的,会增强;
    parentContext [开启] Aop 支持并[托管] Aspect--subContext [开启] Aop 支持 : 注册在父\子容器中的bean都会增强;

    [Aop支持]--[Aspect信息]--[异侧]:
    parentContext [开启] Aop 支持----subContext [关闭] Aop 支持并[托管] Aspect : 父子容器中的bean都无增强; Aspect信息 无法被感知到
    parentContext [关闭] Aop 支持并[托管] Aspect----subContext [开启] Aop 支持 : 仅注册在子容器中的bean增强; 子容器可以感知到 Aspect信息

    结论:
    bean的注册容器开启了Aop支持,其次该注册容器能感知到Aspect信息,则该容器中的注册的bean不管被谁取用都会被增强.
    展开
    
     5
  • 碧雪天虹
    2019-04-28
    foo 和 bar 绕着晕, 改了一下代码, 不晕了
    @Configuration
    @EnableAspectJAutoProxy
    public class FooConfig {
        @Bean
        public TestBean testBeanX() {
            return new TestBean("parentX");
        }

        @Bean
        public TestBean testBeanY() {
            return new TestBean("parentY");
        }

        @Bean
        public FooAspect fooAspect() {
            return new FooAspect();
        }
    }


        <bean id="testBeanX" class="geektime.spring.web.context.TestBean">
            <constructor-arg name="context" value="childX" />
        </bean>


    hello parentX
    after hello()
    =============
    hello childX
    after hello()
    hello parentY
    after hello()
    展开

    作者回复: 发现你这是个好办法,我自己念foo和父都觉得会让人搞不清楚,当时像你这么机智就好了

    
     5
  • Charles
    2019-04-25
    @EnableAspectJAutoProxy
    老师,该注解如果加在配置类上,只会对配置类内部的切面Bean生效;如果加在启动类上,会对整个工程中所有的切面Bean生效?可以这么理解吗?

    作者回复: 不是啊,如果是个单纯的SpringBoot应用程序,加在随便哪个配置类上就行了,Application那个类也是个配置类,大家都是一样的。我在这个例子里是在演示不同的上下文,这个注解其实就是帮忙配了些东西,它配在哪个上下文里,哪里就会有AOP的增强。

    
     3
  • 锋芒
    2019-06-18
    既然fooContext是barContext的父级,按java继承的原理。 barContext 应该也均有父级的设置即 也能用父级的增强配置才对 ? 老师麻烦解惑一下。 谢谢

    作者回复: 这个继承和Java的继承没啥关系啊。父Context里的增强只能看到自己Context里的Bean,并看不到子Context的东西,所以也没法增强。

    
     2
  • Tarn
    2019-04-30
    老师,我在阅读源码的时候发现applicationContext的getBean方法是直接调用容器里beanfactory的getBean方法,并没有看见向父容器中查询bean的过程,而beanfactory的getBean方法则有一个向父beanfactory递归getbean方法的过程,那么是不是可以理解为父applicationcontext的实质就是父beanfactory?但是我也没有看见设置父application的方法中有将beanfactory从父applicationcontext提取出来的规程,只有一个merge方法,也看不太懂,所以还想请教一下老师子容器从父容器中获得bean的步骤,谢谢老师!

    作者回复: ApplicationContext这个接口本身就是extends了BeanFactory的,所以ApplicationContext就是BeanFactory。如果你去看ClassPathXmlApplicationContext,初始化时传入parent,最终是调用了setParent()方法,然后获取Bean时,resolveBean()方法在当前上下文没找到Bean定义时会去父上下文找的。

    
     2
  • shaohsiung
    2019-04-05
    老师,在Spring Boot中,如果我添加了一个配置类,并在这个配置类中装配了Bean,那么我们怎么知道这些Bean会被那个容器管理,web容器还是root容器
    
     2
  • Lee KouKuKing
    2019-03-19
    老师你好,请教几个问题,谢谢
    1、这个例子中的FooAspect中定义的AfterReturning切点是会作用到id为testBean开头的bean的所有方法吧?

    作者回复: 是的,testBean打头的

     1
     2
  • Senior6623
    2019-08-04
    老师,有一个疑问,同名Bean(fooAspect)为何不会报错?因为在不同上下文中吗?

    作者回复: 子上下文在使用时,里面的同ID Bean会覆盖父上下文里的那个Bean。

    
     1
  • 晴天
    2019-03-22
    老师讲讲springboot做了哪些改进,从而不需要再分别指定componentscan啊
    springboot中也有父子上下文吗
    
     1
  • 黄平
    2019-12-11
    为什么config配置的就是父上下文,而xml配置的就是子上下文呢?

    作者回复: 因为我们的代码里是这么写的呀,你可以在看看我们的示例

    
    
  • 刘丹
    2019-10-06
    请问FooConfig类里的FooAspect这个bean为什么会影响类里另外2个bean(testBeanX、testBeanY)的切面?

    作者回复: 我写了@AfterReturning("bean(testBean*)"),那拦截到testBeanX和testBeanY就是应该的。

    
    
  • ace
    2019-09-02
    SpringBoot环境中只有一个容器-AnnotationConfigEmbeddedWebApplicationContext吧?
    
    
  • 王善鹏
    2019-08-29
    老师,FooConfig中的fooAspect() 函数的作用是什么

    作者回复: 通过@Bean注解配置了一个FooAspect类型的Bean

    
    
  • 不能如期而至
    2019-08-19
    运行老师的示例我的理解是:当切面是在父上下文中时,父上下文和子上下文中匹配的Bean都会被织入增强。但是当切面是在子上下文中时,只有子上下文中匹配的Bean会织入增强。 另外,如果没有设置父子上下文,则SpringBoot中默认只有一个上下文。 不知我理解的对不对。
    
    
  • york
    2019-07-30
    两个问题:
    1. bar context(作为foo context的子context)中声明的bean,为何在http://localhost:8080/actuator/beans里面是看不到的?
    2. 如果把bar context的配置,由xml方式改为annotation方式,如何通过代码指定foo context为其父context?

    作者回复: 1. 我们的两个ApplicationContext并不是/beans显示的,所以看不到
    2. 有setParent()方法,你可以试试

    
    
  • tinys
    2019-07-29
    SPRING CONTEXT MARK
    父子上下文基于委托机制.若子上下文找不到bean,才会委托父context来寻找bean.
    因此,
    父上下文中的bean的切入仅支持父context的bean,
    子上下文的bean只支持子context的bean.

    ----------
    引用某同学的语录
    代码解释:
    fooContext.getBean("testBeanX"),在父上下文查找 testBeanX,命中直接返回 testBeanX(foo)。
    barContext.getBean("testBeanX"),在子上下文查找 testBeanX,命中直接返回 testBeanX(bar),因为切面是在父context的,因此无aop.
    barContext.getBean("testBeanY"),在子上下文查找 testBeanY,未命中;委托父上下文查找,命中,返回 testBeanY(foo)。

    ----------
    展开
    
    
  • Fortune
    2019-06-27
    非常感谢老师的课程,有个疑问就是:这节课是不是类似的说明了,在spring中,有个全文上下文ApplicationContext,在配置文件的情况下,通过配置加载对于的xml文件,把bean注入到spring的Ioc里面,然后再mvc这块,有个webApplicationContext,这个负责来加载有关web请求的bean进入Ioc,本人小白,也很感谢老师带我们读了一下源码,真的受益匪浅哈。

    作者回复: 传统的Spring MVC工程的确是有两个上下文的,和你理解的差不多。

    
    
我们在线,来聊聊吧