spring-boot之使用 Spring Boot 的 AOP

虾米哥 阅读:8 2024-05-22 17:00:29 评论:0

我在 STS 的 Spring Boot 启动项目中使用这个 Spring AOP 代码。在调试了一段时间后,我没有看到 AspectJ 语法有任何问题。 Maven 依赖项由 STS 为 AOP 启动项目生成。这段代码中是否有明显的遗漏,比如注释?另一个问题可能与 AOP 启动项目有关,或者与我尝试在 @PostConstruct 中测试代码的方式有关。方法。

我安装了 AJDT,但似乎 STS 应该在 IDE 中自己显示 AspectJ 标记。对 ?我没有看到标记。 STS 中包含哪些其他 AspectJ 调试选项? -Xlint是我在 Eclipse/AJDT 中使用的。

StateHandler.java

public class StateHandler<EVENTTYPE extends EventType> { 
 
 
private State<EVENTTYPE> state; 
 
private Event<EVENTTYPE> event; 
 
public StateHandler(State<EVENTTYPE> state, Event<EVENTTYPE> event) { 
    this.state = state; 
    this.event = event; 
} 
 
 
public void handle( Event<EVENTTYPE> event ){ 
 
    state = state.handle( event ); 
 
} 
 
public State<EVENTTYPE> getState() { 
    return state; 
} 
 
} 

设备记录器.java

    @Aspect 
    @Component 
    public class DeviceLogger { 
 
    private static Logger logger = Logger.getLogger("Device"); 
 
 
        @Around("execution(* com.devicemachine.StateHandler.*(..))") 
        public void log() { 
            logger.info( "Logger" ); 
        } 
} 

LoggerApplication.java

@SpringBootApplication 
public class LoggerApplication { 
 
    private static Logger logger = Logger.getLogger("Device"); 
 
 
    public static void main(String[] args) { 
 
        SpringApplication.run(LoggerApplication.class, args); 
 
    } 
 
    @PostConstruct 
    public void log(){ 
        DeviceState s = DeviceState.BLOCKED; 
        StateHandler<DeviceEvent> sh = new StateHandler<DeviceEvent>( s, 
                                            Event.block(DeviceEvent.BLOCKED, "AuditMessage") ); 
        sh.handle(Event.block(DeviceEvent.UNBLOCKED, "AuditMessage")); 
    } 
} 

请您参考如下方法:

有 3 个明显的错误和 1 个不那么明显的错误。

  • 您的方面是错误的,并且会破坏正确的方法执行。使用环绕方面时,您必须始终返回 Object并使用 ProceedingJoinPoint并调用proceed()在那。
  • 您正在自己创建类的新实例,默认情况下,Spring 使用基于代理的 AOP,并且只会代理它知道的 bean。
  • @PostConstruct方法可能是代理尚未创建并且没有任何内容被拦截
  • 您需要使用基于类的代理才能启用添加 spring.aop.proxy-target-class=true给您的application.properties .默认情况下,使用基于接口(interface)的 JDK 动态代理。

  • 修复方面

    您当前的方面不使用 ProceedingJoinPoint因此,实际的方法调用永远不会。接下来,如果您现在有一个返回值的方法,它会突然返回 null .因为你没有调用 proceedProceedingJoinPoint .
    @Around("execution(* com.devicemachine.StateHandler.*(..))") 
    public Object log(ProceedingJoinPoint pjp) throws Throwable { 
        logger.info( "Logger" ); 
        return pjp.proceed(); 
    } 
    

    创建一个 bean 来修复代理和 @PostConstruct
    @SpringBootApplication 
    public class LoggerApplication { 
     
        private static Logger logger = Logger.getLogger("Device"); 
     
        public static void main(String[] args) { 
            ApplicationContext context = SpringApplication.run(LoggerApplication.class, args); 
            StateHandler<DeviceEvent> sh = context.getBean(StateHandler<DeviceEvent>.class); 
            sh.handle(Event.block(DeviceEvent.UNBLOCKED, "AuditMessage")); 
        } 
     
        @Bean 
        public StateHandler<DeviceEvent> auditMessageStateHandler() { 
            return new StateHandler<DeviceEvent>(DeviceState.BLOCKED, Event.block(DeviceEvent.BLOCKED, "AuditMessage") ); 
        } 
     
    } 
    

    添加属性以启用类代理

    在您的 application.propertiessrc\main\resources添加以下属性,其值为 true
    spring.aop.proxy-target-class=true 
    


    标签:Spring
    声明

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    关注我们

    一个IT知识分享的公众号