Spring AOP 未拾取 AOP 注解

问题描述 投票:0回答:1

我有一个使用 AOP 的项目——一个示例程序——它可以工作。我创建了一个以相同的方式实现 AOP 的项目(据我所知......),但不起作用。

pom.xml

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>6.0.11</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

AppConfig.java

@Configuration
@ComponentScan(basePackages = {
        "com.phil.cardgame.aspects",
        "com.phil.cardgame.service"
})
@EnableAspectJAutoProxy()
public class AppConfig {
}

EventAspect.java

@Aspect
@Component
public class EventAspect {
    @Autowired
    EventRepository eventRepository;

    //@Around("execute(* com.phil.cardgame.service.GameService.createGame())")
    //@Around("execute(* com.phil.cardgame.service.*.*(..))")
    @Around("invalid text")
    public long registerCreateGame(ProceedingJoinPoint joinPoint) throws Throwable{
        String action = joinPoint.getSignature().toString();
        long gameId = (long) joinPoint.proceed();
        eventRepository.addEvent(action,gameId,null);
        System.out.println(">>> got here");
        return gameId;
    }

在EventAspect.java中,您可以看到我尝试过的注释@Around建议。最后一个(无效)不会产生错误。如果我在工作项目中尝试相同的操作,则会收到错误:“切入点格式不正确”。所以看起来我的 EventAspect 没有作为一个方面被检查。

我检查了许多其他类似的问题,但我仍然看不出我做错了什么 - 有什么想法吗?

aop aspectj spring-aspects
1个回答
0
投票

我克隆了你的项目。你的方面有效。尽管与您的问题无关,但只是为了好玩让我们

  • 将建议类型从
    @Around
    更改为
    @AfterReturning
    ,假设您只想记录成功的呼叫;否则,您将混合使用
    @Around
    加上 try-finally 作为第一个建议,并使用
    @After
    作为其他建议,
  • 分解一些常见功能以减少代码重复,
  • 添加一些日志记录,
package com.phil.cardgame.aspects;

import com.phil.cardgame.model.Deck;
import com.phil.cardgame.repository.EventRepository;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class EventAspect {
  @Autowired
  EventRepository eventRepository;

  @Pointcut("within(com.phil.cardgame.service.GameService)")
  public void inGameService() {}

  @AfterReturning(value = "inGameService() && execution(* createGame())", returning = "gameId")
  public void registerCreateGame(JoinPoint joinPoint, Long gameId) {
    addEvent(joinPoint, gameId, null);
  }

  @AfterReturning("inGameService() && execution(* *(..)) && args(gameId, playerId)")
  public void registerPlayerAction(JoinPoint joinPoint, long gameId, String playerId) {
    addEvent(joinPoint, gameId, playerId);
  }

  @AfterReturning("inGameService() && execution(* *(..)) && args(gameId, deck)")
  public void registerDeckAction(JoinPoint joinPoint, long gameId, Deck deck) {
    addEvent(joinPoint, gameId, null);
  }

  @AfterReturning("inGameService() && execution(* *(..)) && args(gameId)")
  public void registerGameAction(JoinPoint joinPoint, long gameId) {
    addEvent(joinPoint, gameId, null);
  }

  private void addEvent(JoinPoint joinPoint, long gameId, String playerId) {
    System.out.println(joinPoint);
    eventRepository.addEvent(joinPoint.getSignature().toString(), gameId, playerId);
  }
}

现在,像这样更改主程序:

package com.phil.cardgame;

import com.phil.cardgame.service.GameService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class CardgameApplication {
  public static void main(String[] args) {
    try (ConfigurableApplicationContext context = SpringApplication.run(CardgameApplication.class, args)) {
      GameService gameService = context.getBean(GameService.class);
      gameService.createGame();
      gameService.addDeckToGame(1, gameService.createDeck());
      gameService.addPlayerToGame(1, "jane");
      gameService.findGame(1);
    }
  }
}

控制台日志将显示:

execution(Long com.phil.cardgame.service.GameService.createGame())
execution(void com.phil.cardgame.service.GameService.addDeckToGame(long,Deck))
execution(Player com.phil.cardgame.service.GameService.addPlayerToGame(long,String))
execution(Game com.phil.cardgame.service.GameService.findGame(long))

对我来说,看起来一切都很顺利。

© www.soinside.com 2019 - 2024. All rights reserved.