2014-10-30 2 views
1

Я использую Spring4 вместе с Spring 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, может ли кто-нибудь помочь мне с этим?

+0

Ваш совет ничего не возвращает. – zeroflagL

+0

@zeroflagL, что вы имеете в виду, ничего не возвращает? Должен ли я опубликовать что-нибудь еще, чтобы описать проблему? – Jaskey

+0

'commandService()' возвращает бит 'CommandService'. Когда вы используете AOP, он больше не вызывается напрямую, но вместо этого вызывается 'debug()'. И 'debug()' ничего не возвращает. Итак, как вы должны получить экземпляр CommandService? – zeroflagL

ответ

2

Ваш @ComponentScan пытается разрешить и отключить ваши зависимости в CoreController. Когда он пытается разрешить зависимость, он находит @Bean в вашем классе Application. Затем он пытается разрешить эту зависимость, вызывая 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

Вы имеете в виду actully, мы должны позволить каждому совету советом возвращать объект? – Jaskey

+0

Как правило, он должен возвращать что-то или бросать исключение. Я не могу придумать ни одного случая, когда совет @Around не вернется, следуйте этому шаблону. – mkobit

Смежные вопросы