spring的应用上下文理解

  • Post author:
  • Post category:其他


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



一、先说结论
  1. 子context没开启aop,父context开启了aop并且开启了切面的增强,则通过父context取得的bean会有切面增强(通过子context调用的是继承的父context的方法取得的bean也是会有切面增强的),通过子context取得的bean没有切面增强
  2. 子context开启aop并且开启了切面的增强,父context没开启aop,则通过父context取得的bean没有切面增强(通过子context调用的是继承的父context的方法取得的bean也是没有切面增强的),通过子context取得的bean会有切面增强
  3. 子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. 上面的代码是情况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的方法取得的,所以有切面增强
  1. 情况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
  1. 情况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的应用上下文理解

宁静致远!



版权声明:本文为TY_zhong原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。