I\'m trying to use automatic dependency injection via Spring\'s @Configurable annotation w/ @Resource on the fields needing injection. This involved some setup, like passing
I found the reason; because custom beans register without order. If your bean was used before the Spring bean org.springframework.context.config.internalBeanConfigurerAspect
was loaded, then @Configurable autowire will not work.
And my solution is like below:
@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED)
@EnableSpringConfigured
@ComponentScan(basePackages = "zhibo")
public class AppConfig extends WebMvcConfigurationSupport {
@Bean
public DemoProcessor demoProcessor() {
return new DemoProcessor();
}
}
public class DemoProcessor implements BeanPostProcessor,BeanDefinitionRegistryPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
Stream.of(beanDefinitionNames).forEach(System.err::println);
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
String[] beanDefinitionNames = registry.getBeanDefinitionNames();
Map zhiboBeans = new LinkedHashMap<>();
//1. remove your beans. let spring's beans go ahead
Stream.of(beanDefinitionNames).forEach(beanName->{
BeanDefinition bd = registry.getBeanDefinition(beanName);
if(bd.getBeanClassName()!=null && bd.getBeanClassName().startsWith("zhibo.")) {
registry.removeBeanDefinition(beanName);
zhiboBeans.put(beanName, bd);
}
});
//2. register your beans again
zhiboBeans.forEach((k,v)->registry.registerBeanDefinition(k, v));
}
}