I customized a Annotation @CustomizedAutowired like @Autowired by using BeanPostProcessor (InjectBeanPostProcessor.java), but I got a NullPointerException when AOP is used.
- Why it is null when using AOP?
- Why DemoController seems to be proxied twice when using AOP?
- what should I do, so that @CustomizedAutowired can work just like @Autowired?
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
public @interface CustomizedAutowired {}
@RestController
@RequestMapping("/hello")
public class DemoController {
@CustomizedAutowired
private InjectBean injectBean;
@GetMapping("/world")
public LocalDateTime hello() {
injectBean.hello(); // injectBean is null
return LocalDateTime.now();
}
}
@Aspect
@Component
public class AopDemo {
@Pointcut("execution(public java.time.LocalDateTime *(..))")
public void pointcut() {}
@AfterReturning(pointcut = "pointcut()")
public void round() {
System.out.println("after returning");
}
}
@Component
public class InjectBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Class<?> targetClass = bean.getClass();
while (targetClass != null) {
Field[] fields = targetClass.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(CustomizedAutowired.class)) {
field.setAccessible(true);
try {
field.set(bean, new InjectBean());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
targetClass = targetClass.getSuperclass();
}
return bean;
}
}
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@CustomizedAutowired
private InjectBean injectBean;
@Override
public void run(String... args) throws Exception {
System.out.println("instance -> " + this);
injectBean.hello(); // works fine here
}
}
Here is the result: