I am using Spring4
along with Spring Boot
.
Before I tired to use AOP, my Bean(CommandService),which is used in the controller, is auto injected well, but after I tired to use AOP to collect some debug message, the bean becomes null!
Here is my 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
}
}
My controller that throws null pointer:
@Controller
public class CoreController {
@Autowired
CommandService commandService;//here the service is null after using aop
//...some request methods
}
The Aspect which I added just now:
//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;
}
}
}
I am new to Spring, can anybody help me with this?
Your @ComponentScan
is trying to resolve and autowire your dependencies into CoreController
. When it tries to resolve the dependency it finds the @Bean
in your Application
class. It then tries to resolve this dependency by calling Application.commandService()
. When this method is called, it sees the matching @Pointcut
and invokes your advice method. Since your @Advice
is not returning anything, the callers will also see that nothing was returned, and it will say that that resolution of that dependency returned null
.
The fix here is just to change your @Around
advice to return the value of your invocation.
@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;
}
}