2014-10-30 97 views
1

我正在使用Spring4以及Spring Boot注入的bean在使用AOP后变为空

在我厌倦了使用AOP之前,我在控制器中使用的Bean(CommandService)被自动注入,但是当我厌倦了使用AOP来收集一些调试消息后,这个bean就变成了空的!

这里是我的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; 
     } 
    } 
} 

我是新来的春天,有人可以帮我吗?

+0

您的建议不会返回任何内容。 – zeroflagL 2014-10-30 08:22:06

+0

@zeroflagL,你什么意思不返回任何东西?我是否需要发布其他内容来描述问题? – Jaskey 2014-10-30 09:25:16

+0

'commandService()'返回一个'CommandService' bean。当你使用AOP时,它不再被直接调用,而是调用“debug()”。而'debug()'不返回任何东西。那么你应该如何获得一个'CommandService'实例? – zeroflagL 2014-10-30 09:33:07

回答

2

您的@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; 
    } 
} 
+0

你的意思是说,我们应该让每个周围的建议返回一个对象? – Jaskey 2014-10-31 06:50:57

+0

它通常应该返回一些东西或抛出异常。我想不出任何@Around建议不会返回的情况。 – mkobit 2014-10-31 08:01:16