简体   繁体   English

Spring AOP中的切入点“或”组合

[英]Pointcut “or” composition in Spring AOP

I have a class BigManPlay implements an interface Performance : 我有一个BigManPlay类, BigManPlay实现了Performance接口:

@Component
public class BigManPlay implements Performance {
    @Override
    public void perform() {
        System.out.println("Performing 111!");
    }

    @Override
    public void perform2() {
        System.out.println("Performing 222!");
    }
}

Then, I expect the perform() method and every method(means perform2() ) in the Performance interface are the advice targets. 然后,我希望Performance接口中的perform()方法和每个方法(意味着perform2() )都是建议目标。 So I write the following aspect class: 因此,我编写了以下方面类:

@Aspect
public class Audience {

    @Pointcut("execution(* Chapter_4_2_1.concert.Performance.perform(..)) or within(Chapter_4_2_1.concert.Performance+)")
    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!!!");
    }
}

Then a java config class to wire beans: 然后是一个Java config类来连接bean:

@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = {"Chapter_4_2_1.concert"})
public class ConcertConfig {
    @Bean
    public Audience audience() {
        return new Audience();
    }
}

Then the UT class: 然后是UT类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=ConcertConfig.class)
public class PerformanceTest {

    @Autowired
    Performance bigManPlay;

    @Rule
    public final SystemOutRule log = new SystemOutRule().enableLog();

    @Test
    public void testWithPerformance() {
        log.clearLog();
        bigManPlay.perform();
        assertEquals("Silencing cell phones" + System.lineSeparator()
                + "Taking seats" + System.lineSeparator()
                + "Performing 111!" + System.lineSeparator()
                + "CLAP CLAP CLAP!!!" + System.lineSeparator(), log.getLog());
    }


    @Test
    public void testWithPerformance2() {
        log.clearLog();
        bigManPlay.perform2();
        assertEquals("Silencing cell phones" + System.lineSeparator()
            + "Taking seats" + System.lineSeparator()
            + "Performing 222!" + System.lineSeparator()
            + "CLAP CLAP CLAP!!!" + System.lineSeparator(), log.getLog());
    }
}

UT is failed. UT失败。 testWithPerformance2() only output testWithPerformance2()仅输出

Performing 222!

The within(Chapter_4_2_1.concert.Performance+) doesn't take effect, why? within(Chapter_4_2_1.concert.Performance+)无效,为什么?

The syntax for pointcut composition for "or" is || “或”的切入点合成的语法为|| .

Pointcut0 || Pointcut1 Pointcut0 || Pointcut1 each join point picked out by either Pointcut0 or Pointcut1 Pointcut0 || Pointcut1 Pointcut0Pointcut1拾取的每个连接点

That will look like 看起来像

@Pointcut("execution(* Chapter_4_2_1.concert.Performance.perform(..)) || within(Chapter_4_2_1.concert.Performance+)")

Essentially the parser finds the first pointcut expression, the execution , and stops parsing because there are no other composition tokens in the remaining expression. 本质上,解析器找到第一个切入点表达式, execution和,并停止解析,因为在其余表达式中没有其他合成标记。 You could write anything 你什么都可以写

@Pointcut("execution(* Chapter_4_2_1.concert.Performance.perform(..)) blabla")

and it wouldn't fail to parse. 而且它不会失败。 It would create a valid pointcut for that execution . 它将为该execution创建有效的切入点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM