JavaConfig方式配置没有此现象,而xml配置出现这样的问题。共同代码如下:
package springinaction.chapter4; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; /** * @author JUANJUAN * @time 2018年1月8日 下午2:27:26 */ @Aspect public class Audience { @Pointcut("execution(** springinaction.chapter4.Performance.perform(..))") public void performance() {} @Before("performance()") public void silenceCellPhones() { System.out.println("Silencing cell phones"); } @Before("performance()") public void takeSeats() { System.out.println("Taking seats"); } @AfterReturning("performance()") public void applause() { System.out.println("CLAP CLAP CLAP"); } @AfterThrowing("performance()") public void demandRefund() { System.out.println("Demanding a refund"); } }
package springinaction.chapter4; /** * @author JUANJUAN * @time 2018年1月8日 下午2:34:27 */ public interface Performance { void perform(); }
package springinaction.chapter4; import org.springframework.stereotype.Component; /** * @author JUANJUAN * @time 2018年1月8日 下午2:48:33 */ @Component public class SingPerformance implements Performance{ @Override public void perform() { // TODO Auto-generated method stub System.out.println("Classic Music Performance on"); } }JavaConfig配置类
package springinaction.chapter4; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; /** * @author JUANJUAN * @time 2018年1月8日 下午2:35:27 */ @Configuration @ComponentScan @EnableAspectJAutoProxy //启动AspectJ自动代理 public class ConcertConfig { @Bean public Audience audience() { return new Audience(); } }
xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="springinaction.chapter4" /> <aop:aspectj-autoproxy /> <!-- 在xml配置中,配置Audience后,aop执行了两次,因为生成了两个audience代理。移除这个bean或者在自动扫描中去除aop的类 <bean class="springinaction.chapter4.Audience"/> --> </beans>测试类:
package springinaction.chapter4; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author JUANJUAN * @time 2018年1月8日 下午2:44:50 */ public class AOPTest { @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=ConcertConfig.class) public static class JavaConfigTest{ @Autowired private Performance perform; @Test public void test() { perform.perform(); } } @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath*:aop.xml") public static class XMLTest{ @Autowired private Performance perform; @Test public void test() { perform.perform(); } } }
xml配置方式中移除
<bean class="springinaction.chapter4.Audience"/>之后,aop执行恢复正常。应该是自动扫描时也创建了一个代理,导致容器中两个aop代理,执行了两次。
但是有一个疑问,就是JavaConfig配置类中也配置了自动扫描,却没有执行两次,移除JavaConfig配置类中的
@Bean public Audience audience() { return new Audience(); }后,aop失效,也就是说明JavaConfig配置类中ComponentScan并没有扫描被@Aspect注解的Audience。
而xml文件中的component-scan却扫描了被@Aspect注解的Audience。
这两个方式的实现方式是不一样的?哪里不一样?