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