我有一个使用 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 没有作为一个方面被检查。
我检查了许多其他类似的问题,但我仍然看不出我做错了什么 - 有什么想法吗?
我克隆了你的项目。你的方面有效。尽管与您的问题无关,但只是为了好玩让我们
@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))
对我来说,看起来一切都很顺利。