spring的应用上下文理解

此处使用丁雪丰大神的课程代码,以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的应用上下文理解

宁静致远!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值