英文:
@Autowired instance of Service class is null in the application.java
问题
@Service
public class TokenServiceImpl implements TokenService{
private final Settings settings;
private final RestTemplate restTemplate;
@Autowired
public TokenServiceImpl(Settings settings, @Qualifier("rstProxy") RestTemplate restTemplate) {
this.settings= settings;
this.restTemplate = restTemplate;
}
//...
}
Application.java
@SpringBootApplication
@EnableAsync
@EnableScheduling
public class Application extends SpringBootServletInitializer {
@Autowired
private TokenService tokenService; // 返回 null
//.......
@Bean("rstProxy")
public RestTemplate restTemplateWithProxy() {
final List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
messageConverters.add(new ByteArrayHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
messageConverters.add(new ResourceHttpMessageConverter());
messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
messageConverters.add(new MappingJackson2HttpMessageConverter());
final RestTemplate restTemplate = new RestTemplate();
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(new AuthorizationInterceptor(tokenService));
restTemplate.setInterceptors(interceptors);
restTemplate.getMessageConverters().addAll(messageConverters);
restTemplate.setRequestFactory(factory);
return restTemplate;
}
}
为什么 TokenService 返回 null?但如果我从构造函数中移除 @Qualifier("rstProxy")
,它就能工作。你有解决方案吗?我需要这个 @qualifier。
英文:
I am a little confused,why @Autowired instance of the Service class is null
@Service
public class TokenServiceImpl implements TokenService{
private final Settings settings;
private final RestTemplate restTemplate;
@Autowired
public TokenServiceImpl(Settings settings, @Qualifier("rstProxy") RestTemplate restTemplate) {
this.settings= settings;
this.restTemplate = restTemplate;
}
//...
}
Application.java
@SpringBootApplication
@EnableAsync
@EnableScheduling
public class Application extends SpringBootServletInitializer {
@Autowired
private TokenService tokenService; // return null
//.......
@Bean("rstProxy")
public RestTemplate restTemplateWithProxy() {
final List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
messageConverters.add(new ByteArrayHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
messageConverters.add(new ResourceHttpMessageConverter());
messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
messageConverters.add(new MappingJackson2HttpMessageConverter());
final RestTemplate restTemplate = new RestTemplate();
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(new AuthorizationInterceptor(tokenService));
restTemplate.setInterceptors(interceptors);
restTemplate.getMessageConverters().addAll(messageConverters);
restTemplate.setRequestFactory(factory);
return restTemplate;
}
}
Why the TokenService returns null ?
But If I remove the @Qualifier("rstProxy")
from my constructor, it works. Do you have a solution ? I need this @qualifier
答案1
得分: 1
第一点:Spring Bean 的实例化顺序没有保证,除非您明确指定。
@Autowired
@Lazy // 这将在请求时加载 Bean
private TokenService tokenService;
如果上述方法不起作用,可以继续尝试重构您的 TokenServiceImpl,使其在构造函数之后接受 setter 方法:
private RestTemplate restTemplate;
public TokenServiceImpl(Settings settings) {
this.settings= settings;
}
@Autowired
public void setRestTemplate(@Qualifier("rstProxy") RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
现在,TokenService 将在不等待 RestTemplate 的情况下创建。然后,当 RestTemplate 被创建时,它可以通过我们创建的 setter 方法注入到 TokenService 中。
英文:
First: Spring beans are instantiated in no guaranteed order, unless you specify it
@Autowired
@Lazy //this will load Bean when it is requested
private TokenService tokenService;
If above not work then continue and try to refactor your TokenServiceImpl to accept setter method after constructor:
private RestTemplate restTemplate;
public TokenServiceImpl(Settings settings) {
this.settings= settings;
}
@Autowired
public void setRestTemplate(@Qualifier("rstProxy") RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
Now TokenService is created without waiting for the RestTemplate.
Then, when the RestTemplate is created, It can inject it into the TokenService via setter method that we created.
答案2
得分: 0
@SpringBootApplication
本身不是 @Component
,不会注入任何依赖到你的 Application 类(它实际上不是一个 Bean)。你需要明确告诉 Spring,Application 类本身也是一个 Bean:
@Service // <--- 在应用程序上下文中注册为服务
@SpringBootApplication
@EnableAsync
@EnableScheduling
public class Application extends SpringBootServletInitializer {
@Autowired
private TokenService tokenService;
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
但我建议你只将你的应用程序作为启动 Spring 应用程序的入口点,而不要直接参与其中。
英文:
@SpringBootApplication
itself is not a @Component
and no dependencies will be injected into your Application class (it's simply not a bean). You need to explicitly tell Spring that the Application class itself is a bean too:
@Service // <-- register as service in application context
@SpringBootApplication
@EnableAsync
@EnableScheduling
public class Application extends SpringBootServletInitializer {
@Autowired
private TokenService tokenService;
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
But I'd recommend using your application only as entry point to start the Spring application, but not take part in it itself.
答案3
得分: 0
另一个答案,第二个:
当您在TokenServiceImpl的构造函数中将@Lazy注解添加到RestTemplate bean时,它告诉容器只有在第一次调用时才创建该bean,而不是在应用程序启动时。
@Autowired
public TokenServiceImpl(Settings settings, @Lazy @Qualifier("rstProxy") RestTemplate restTemplate) {
this.settings= settings;
this.restTemplate = restTemplate;
}
这可能会使您的tokenServiceImpl bean不为空。
英文:
Another answer, second one:
When you add @Lazy annotation to the RestTemplate bean in the constructor of TokenServiceImpl, it tells to Container to create this bean only when it is first time called, not at the application startup.
@Autowired
public TokenServiceImpl(Settings settings, @Lazy @Qualifier("rstProxy") RestTemplate restTemplate) {
this.settings= settings;
this.restTemplate = restTemplate;
}
This above probably make your tokenServiceImpl bean to not be a null.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论