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。
这两个方式的实现方式是不一样的?哪里不一样?