【问题标题】:Injected bean becomes null after using AOP使用 AOP 后注入的 bean 变为 null
【发布时间】:2014-10-30 03:38:45
【问题描述】:

我正在使用Spring4Spring Boot

在我厌倦了使用AOP之前,我在控制器中使用的Bean(CommandService)很好地自动注入,但是在我厌倦了使用AOP收集一些调试消息之后,bean变成了null!

这是我的Application.java

@Configuration
@EnableAutoConfiguration
@ComponentScan({"hello","wodinow.weixin.jaskey"})
public class Application extends  {

public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run(Application.class, args);

    LogUtil.info("Beans provided by Spring Boot:");
    String[] beanNames = ctx.getBeanDefinitionNames();
    Arrays.sort(beanNames);
    for (String beanName : beanNames) {
        LogUtil.info(beanName);
    }
    LogUtil.info("Application Boots completes!");
}

@Bean
public CommandService commandService(){
    LogUtil.debug("CommandService.getInstance()"+ CommandService.getInstance()) ;//here indeed I could see spring executes this and returns a object when application boots
    return CommandService.getInstance();//This returns a singleton instance
}

}

我的控制器抛出空指针:

@Controller
public class CoreController {

    @Autowired
    CommandService commandService;//here the service is null after using aop

    //...some request methods
}

我刚才添加的方面:

//if I comment out these two annoations, the bean will be auto injected well
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(* wodinow.weixin.jaskey..*.*(..))")
    private void debug_log(){};

    @Around("debug_log()")
    public void debug(ProceedingJoinPoint joinPoint) throws Throwable{
        LogUtil.debug("enter "+joinPoint.getSignature());
        try{
           joinPoint.proceed();
           LogUtil.debug("returns from "+joinPoint.getSignature());
        }
        catch(Throwable t){
            LogUtil.error(t.getMessage()+"occurs in "+joinPoint.getSignature(),t);
            throw t;
        }
    }
}

我是 Spring 新手,谁能帮我解决这个问题?

【问题讨论】:

  • 你的建议没有任何回报。
  • @zeroflagL ,你是什么意思不返回任何东西?我需要发布任何其他内容来描述问题吗?
  • commandService() 返回一个 CommandService bean。当您使用 AOP 时,不再直接调用它,而是调用 debug()。而debug() 不返回任何内容。那么你应该如何获得CommandService 实例呢?
  • 哦!我猜你的意思,你的意思是我的 AOP 方法调试已经拦截了 commandService() 的方法,并且该方法应该返回 CommandService ,但它没有?那么问题出现了吗?我是 Spring AOP 的新手。这是我第一次写这个,你能帮我解决一个答案吗?
  • 看看Spring docs for @Around。该建议对其输入/输出有一定的要求。

标签: java spring spring-mvc spring-boot spring-aop


【解决方案1】:

您的@ComponentScan 正在尝试解析您的依赖项并将其自动连接到CoreController。当它尝试解决依赖关系时,它会在您的 Application 类中找到 @Bean。然后它尝试通过调用Application.commandService() 来解决这种依赖关系。调用此方法时,它会看到匹配的 @Pointcut 并调用您的建议方法。由于您的 @Advice 没有返回任何内容,调用者也会看到没有返回任何内容,它会说该依赖项的解析返回了 null

这里的解决方法是更改​​您的 @Around 建议以返回您的调用值。

@Around("debug_log()")
public Object debug(ProceedingJoinPoint joinPoint) throws Throwable{
    LogUtil.debug("enter "+joinPoint.getSignature());
    try{
        // return the invocation
        return joinPoint.proceed();
    }
    catch(Throwable t){
        LogUtil.debug(t.getMessage()+"occurs in "+joinPoint.getSignature(),t);
        throw t;
    }
}

【讨论】:

  • 你的意思是我们应该让每个周围的建议都返回一个对象吗?
  • 它通常应该返回一些东西或者抛出一个异常。我想不出@Around 建议不会按照这种模式返回的任何情况。
【解决方案2】:

你被利用了

joinPoint.proceed(); 

没有return,只需添加return即可

return joinPoint.proceed();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    • 2018-03-08
    • 2021-06-17
    相关资源
    最近更新 更多