You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加Spring AOP后@Autowired注入对象为null引发空指针异常求助

解决Spring AOP引入后@Autowired变量空指针问题

我帮你排查这个空指针异常的问题,大概率是你的切面类没有被Spring正确管理,或者AOP代理机制导致的依赖注入失效,下面给你一步步的解决方案:

1. 确保切面类被Spring容器接管

你的切面代码里没有显示@Aspect和@Component注解——这两个注解是必须的:

  • @Aspect告诉Spring这是一个AOP切面类
  • @Component让Spring把这个切面类纳入IoC容器管理,这样@Autowired才能正常注入依赖

修正后的切面类代码如下:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
public class LoggingAspect {
    // 建议注入接口类型(比如UserService)而非实现类,避免代理类型不匹配问题
    @Autowired 
    private Service service; 

    private final Log log = LogFactory.getLog(this.getClass());

    @Around("execution(* com.kpi.ninja..*.*(..))")
    public Object logTimeMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        System.out.println("Entering in Method : " + joinPoint.getSignature().getName());
        System.out.println("Class Name : " + joinPoint.getSignature().getDeclaringTypeName());
        System.out.println("Target class : " + joinPoint.getTarget().getClass().getName());
        
        Object retVal = joinPoint.proceed();
        
        stopWatch.stop();
        StringBuffer logMessage = new StringBuffer();
        logMessage.append(joinPoint.getTarget().getClass().getName());
        logMessage.append(".");
        logMessage.append(joinPoint.getSignature().getName());
        logMessage.append("(");
        
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            logMessage.append(args[i]).append(",");
        }
        if (args.length > 0) {
            logMessage.deleteCharAt(logMessage.length() - 1);
        }
        
        logMessage.append(")");
        logMessage.append(" execution time: ");
        logMessage.append(stopWatch.getTotalTimeMillis());
        logMessage.append(" ms");
        
        log.info(logMessage.toString());
        return retVal;
    }
}

2. 调整AOP代理方式(如果需要)

Spring默认会根据被代理类是否实现接口选择代理方式:

  • 如果你的Service是接口+实现类的结构,Spring用JDK动态代理(基于接口),这时候注入接口类型就没问题
  • 如果你的Service没有实现接口,或者你需要代理类而非接口,可以强制开启CGLIB代理:
    在application.properties中添加配置:
    spring.aop.proxy-target-class=true
    
    这样Spring会生成子类代理,能更好地支持类类型的依赖注入。

3. 缩小切点表达式范围(可选)

你的切点表达式execution(* com.kpi.ninja..*.*(..))会匹配包下所有类的所有方法,包括Spring内部的Bean,可能引发不必要的代理问题。建议缩小范围到业务层,比如:

@Around("execution(* com.kpi.ninja.service..*.*(..))")

4. 基础检查

别忘了确认你的Service类已经添加了@Service注解,确保它本身是Spring管理的Bean(你说之前项目运行正常,这个大概率没问题,但还是可以快速验证下)。

按照上面的步骤调整后,应该就能解决@Autowired变量的空指针问题了。

内容的提问来源于stack exchange,提问作者Abhishek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:17:50