spring的应用上下文理解

    技术2023-05-09  71

    此处使用丁雪丰大神的课程代码,以aop为例

    一、先说结论
    子context没开启aop,父context开启了aop并且开启了切面的增强,则通过父context取得的bean会有切面增强(通过子context调用的是继承的父context的方法取得的bean也是会有切面增强的),通过子context取得的bean没有切面增强子context开启aop并且开启了切面的增强,父context没开启aop,则通过父context取得的bean没有切面增强(通过子context调用的是继承的父context的方法取得的bean也是没有切面增强的),通过子context取得的bean会有切面增强子context开启aop但没开启切面的增强,父context开启了aop并且开启了切面的增强,则通过父context取得的bean会有切面增强(通过子context调用的是继承的父context的方法取得的bean也是会有切面增强的),通过子context取得的bean也会有切面增强
    二、上代码

    Foo切面 FooAspect.java

    @Aspect @Slf4j public class FooAspect { @AfterReturning("bean(testBean*)") public void printAfter() { log.info("after hello()"); } }

    父context配置 FooConfig.java

    @Configuration @EnableAspectJAutoProxy // 开启aop public class FooConfig { @Bean public TestBean testBeanX() { return new TestBean("foo"); } @Bean public TestBean testBeanY() { return new TestBean("foo"); } @Bean // 开启切面 public FooAspect fooAspect() { return new FooAspect(); } }

    子context配置xml applicationContext.xml

    <!--<aop:aspectj-autoproxy/>--> <bean id="testBeanX" class="geektime.spring.web.context.TestBean"> <constructor-arg name="context" value="Bar" /> </bean> <!--<bean id="fooAspect" class="geektime.spring.web.foo.FooAspect" />-->

    TestBean.java就是接收一个context字符串,然后输出"hello " + context 主程序

    public void run(ApplicationArguments args) throws Exception { ApplicationContext fooContext = new AnnotationConfigApplicationContext(FooConfig.class); ApplicationContext barContext = new ClassPathXmlApplicationContext( new String[] {"applicationContext.xml"}, fooContext); TestBean bean = fooContext.getBean("testBeanX", TestBean.class); bean.hello(); log.info("============="); bean = barContext.getBean("testBeanX", TestBean.class); bean.hello(); bean = barContext.getBean("testBeanY", TestBean.class); bean.hello(); }
    三、运行结果
    上面的代码是情况1 子context没开启aop,父context开启了aop并且开启了切面的增强,则通过父context取得的bean会有切面增强(通过子context调用的是继承的父context的方法取得的bean也是会有切面增强的),通过子context取得的bean没有切面增强 结果如下: hello foo after hello() // 这个bean是由父context取得的,所以有切面增强 hello Bar // 这个bean是由子context取得的,所以没有切面增强 hello foo after hello() // 这个bean是由子context调用的父context的方法取得的,所以有切面增强 情况2:子context开启aop且开启切面增强 修改这两处代码 配置xml applicationContext.xml <!--开启aop--> <aop:aspectj-autoproxy/> <bean id="testBeanX" class="geektime.spring.web.context.TestBean"> <constructor-arg name="context" value="Bar" /> </bean> <!--开启切面增强--> <bean id="fooAspect" class="geektime.spring.web.foo.FooAspect" />

    父context关闭aop,FooConfig.java

    @Configuration //@EnableAspectJAutoProxy // 开启aop public class FooConfig { @Bean public TestBean testBeanX() { return new TestBean("foo"); } @Bean public TestBean testBeanY() { return new TestBean("foo"); } // @Bean // 开启切面 // public FooAspect fooAspect() { // return new FooAspect(); // } }

    结果如下: 子context开启aop并且开启了切面的增强,父context没开启aop,则通过父context取得的bean没有切面增强(通过子context调用的是继承的父context的方法取得的bean也是没有切面增强的),通过子context取得的bean会有切面增强

    hello foo hello Bar after hello() hello foo 情况3:父子context均开启aop,父context开启切面增强 修改这两处代码 配置xml applicationContext.xml <!--开启aop--> <aop:aspectj-autoproxy/> <bean id="testBeanX" class="geektime.spring.web.context.TestBean"> <constructor-arg name="context" value="Bar" /> </bean> <!--<bean id="fooAspect" class="geektime.spring.web.foo.FooAspect" />-->

    父context关闭aop,FooConfig.java

    @Configuration @EnableAspectJAutoProxy // 开启aop public class FooConfig { @Bean public TestBean testBeanX() { return new TestBean("foo"); } @Bean public TestBean testBeanY() { return new TestBean("foo"); } @Bean // 开启切面 public FooAspect fooAspect() { return new FooAspect(); } }

    结果如下: 子context开启aop但没开启切面的增强,父context开启了aop并且开启了切面的增强,则通过父context取得的bean会有切面增强(通过子context调用的是继承的父context的方法取得的bean也是会有切面增强的),通过子context取得的bean也会有切面增强

    hello foo after hello() hello Bar after hello() hello foo after hello()

    完整代码在我的github仓库 spring的应用上下文理解

    宁静致远!

    Processed: 0.008, SQL: 9