@Autowired从Spring Boot中注入的service在WAR中为null。

huangapple go评论111阅读模式
英文:

@Autowired service from Spring Boot is null in WAR

问题

首先,我为给您带来不便道歉,我提供这个咨询是因为我已经花了好几天时间来解决这个问题,但是我找不到正确的解决方案。我有一个名为"fact-electronica-api"的项目,使用Swagger Codegen进行设计,通过它我可以得到执行REST调用的路径。一旦用户进行了这种调用,API项目会与另一个使用Spring Boot的核心项目进行通信,后者会与数据库执行查询。我的问题是,当我在API中对核心中定义的服务进行自动装配(Autowired)时,该服务始终为null。

请原谅我的英语,我来自乌拉圭,我希望您能理解我所面临的问题。为了更好地理解,我已经附上了一些图片。

  • Fact electronica Api

@Autowired从Spring Boot中注入的service在WAR中为null。

  • Factelec-core

@Autowired从Spring Boot中注入的service在WAR中为null。

通过该服务接收REST调用,并与核心进行通信。

@Autowired从Spring Boot中注入的service在WAR中为null。

核心中的服务

@Autowired从Spring Boot中注入的service在WAR中为null。

API对核心的依赖关系

@Autowired从Spring Boot中注入的service在WAR中为null。

Spring Boot初始化器,在您启动Wildfly中的EAR文件时,该项目会自动启动并进行相关设置。

@Autowired从Spring Boot中注入的service在WAR中为null。

如果有人能够指导我解决这个问题,我将不胜感激,提前感谢您。

英文:

first of all I apologize for the inconvenience, I make this consultation because I have spent days with this problem and I do not find the right solution. I have a project called fact-electronica-api designed using swagger codegen, through this I have the paths to perform REST calles. Once the user makes a call of this type the api project communicates with another project that has the core which use Spring Boot and performs the query with the database. The problem I have is that when I make from the api an autowired to the service defined in the core this is null.

Excuse my English, I am from Uruguay, I hope you understand the problem I am facing.For further understanding, I have attached images.

  • Fact electronica Api

@Autowired从Spring Boot中注入的service在WAR中为null。

  • Factelec-core

@Autowired从Spring Boot中注入的service在WAR中为null。

Service through which I receive the rest call and communicate with the core.

@Autowired从Spring Boot中注入的service在WAR中为null。

Service in core

@Autowired从Spring Boot中注入的service在WAR中为null。

Dependence on the api to the core

@Autowired从Spring Boot中注入的service在WAR中为null。

Spring Boot initializer, when you start the ear in wildfly, this project starts automatically and makes the relevant settings.

@Autowired从Spring Boot中注入的service在WAR中为null。

I would be grateful if someone could guide me in solving this problem, thank you in advance.

答案1

得分: 2

似乎 SolicitudApiServicelmpl 不是一个 Spring bean,因此 Spring 不会考虑对所有使用 @Autowired 注解的类字段进行依赖注入。尝试将该类标注为 @Service,将类的实例添加到 Spring 上下文中,或者为 SolicitudApiServicelmpl 创建一个工厂,在其中生成 Spring 代理而不是一个简单的对象。

英文:

Seems like SolicitudApiServicelmpl isn't a Spring bean, so Spring wouldn't consider all class's fields annotated with @Auowired for dependency injection. Try to annotate this class as @Service to add the class's instance to Spring context or create a factory for
SolicitudApiServicelmpl which generates Spring proxy instead of a simple object.

答案2

得分: 1

你没有在创建 SolicitudApiServicelmpl 的 Spring 实例。

Spring 上下文(使 @Autowired 起作用)需要你通过 Spring 创建该实例,而不是使用 Java 的 new SolicitudApiServicelmpl()

你可以使用多种技术来创建该实例,以下是其中一些方法:

使用静态上下文和“手动装配”(不推荐)

  1. public class Main {
  2. private static ConfigurableApplicationContext context;
  3. public static void main(String[] args) {
  4. context = SpringApplication.run(MyApplication.class, args);
  5. }
  6. public static ConfigurableApplicationContext getContext() {
  7. return context;
  8. }
  9. }
  1. public class SolicitudApiServicelmpl {
  2. private ConfigurableApplicationContext context = Main.getContext();
  3. private SolicitudInformacionService solInfServ = context.getBean(SolicitudInformacionService.class);
  4. // 现在 `solInfServ` 不再为空。
  5. // ...
  6. }

在 Spring 上下文中创建 SolicitudApiServicelmpl 实例

  1. @Component
  2. public class SomeClassWithSpringContext {
  3. @Autowired private SolicitudApiServicelmpl solicitudService;
  4. // 这样,@Autowired 应该在 `solicitudService` 实例中起作用。
  5. }

或者使用上下文实例:

  1. @Component
  2. public class SomeClassWithSpringContext {
  3. @Autowired private WebApplicationContext context;
  4. public void someMethodOrSomewhere() {
  5. SolicitudApiServicelmpl service = context.getBean(SolicitudApiServicelmpl.class);
  6. // 这样,@Autowired 应该在 `service` 实例中起作用。
  7. }
  8. }
英文:

You are not creating SolicitudApiServicelmpl spring instance.

Spring context (witch makes @Autowired work) needs you to create that instance thought to Spring and not with a java native new SolicitudApiServicelmpl().

You can create that instance with a lot of techniques, here you have some of them:

Static context with "manual wired" (not recommended)

  1. public class Main {
  2. private static ConfigurableApplicationContext context;
  3. public static void main(String[] args) {
  4. context = SpringApplication.run(MyApplication.class, args);
  5. }
  6. public static ConfigurableApplicationContext getContext() {
  7. return context;
  8. }
  9. }
  1. public class SolicitudApiServicelmpl {
  2. private ConfigurableApplicationContext context = Main.getContext();
  3. private SolicitudInformacionService solInfServ = context.getBean(SolicitudInformacionService.class);
  4. // Now `solInfServ` is not null anymore.
  5. // ...
  6. }

Creating a SolicitudApiServicelmpl instance within the Spring context

  1. @Component
  2. public class SomeClassWithSpringContext {
  3. @Autowired private SolicitudApiServicelmpl solicitudService;
  4. // with this @Autowired should work in the `service` instance.
  5. }

or with the context instance:

  1. @Component
  2. public class SomeClassWithSpringContext {
  3. @Autowired private WebApplicationContext context;
  4. public void someMethodOrSomewhere() {
  5. SolicitudApiServicelmpl service = context.getBean(SolicitudApiServicelmpl.class);
  6. // with this @Autowired should work in the `service` instance.
  7. }
  8. }

答案3

得分: 0

经过 Nurio Fernández 和 Andrei Kovrov 给予我的帮助,我能够找到实现我想要做的事情的正确方法。

首先,我将 Spring 集成到了 API 中,而不仅仅是核心部分,将 Spring Boot 从核心部分移动到了 API 中,结果在 API 中出现了以下类。

Api - ApplicationInitializer.java

  1. @Order(Ordered.HIGHEST_PRECEDENCE)
  2. @SpringBootApplication(scanBasePackages = {"com.factelcore.*","uy.com.antel.fact.*"})
  3. @EnableJpaRepositories("com.factelcore.repository")
  4. public class ApplicationInitializer extends SpringBootServletInitializer {
  5. public static void main(String[] args){
  6. SpringApplication.run(ApplicationInitializer.class,args);
  7. }
  8. @Override
  9. protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
  10. return application.sources(applicationClass);
  11. }
  12. private static Class<ApplicationInitializer> applicationClass = ApplicationInitializer.class;
  13. }

通过这样做,我确保在 API 中有了一个 Spring 上下文,我可以在其中进行操作。当我从这里启动 Spring 时,我扫描了所有的 API 和核心文件,并对 Bean 进行了适当的配置。

在这样做之后,我需要捕获上下文以恢复在核心中定义的 Bean,这样我就可以使用核心中定义的 @Service 类。为此,我创建了以下类:

Api - AppContextUtil.java

  1. @Component
  2. public class AppContextUtil implements ApplicationContextAware {
  3. @Autowired
  4. private WebApplicationContext context;
  5. private static ApplicationContext appContext;
  6. @PostConstruct
  7. public void init() {
  8. if (context != null) {
  9. setApplicationContext(context);
  10. }
  11. }
  12. @Override
  13. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  14. AppContextUtil.appContext = applicationContext;
  15. }
  16. public static ApplicationContext getContext() {
  17. return appContext;
  18. }
  19. }

完成这一步后,使用 SolicitudApiServiceImpl,我可以通过以下方式在特定时刻调用所需的 Bean:

Api - SolicitudApiServiceImpl.java

  1. ApplicationContext cont = AppContextUtil.getContext();
  2. SolicitudInformacionService solInfServ = cont.getBean(SolicitudInformacionService.class);

我不知道这是否是理想的方法,但在我的情况下对我起作用,如果有人知道更好的方法,请随意告诉我,以便我可以改进代码。非常感谢!

英文:

after the help that was given to me by Nurio Fernández and Andrei Kovrov i was able to find out the right way to accomplish what i wanted to do.

First of all I integrate Spring into the api, and not only into the core, moving spring boot from the core to the api, resulting in this class in the api.

> Api - ApplicationInitializer.java

  1. @Order(Ordered.HIGHEST_PRECEDENCE)
  2. @SpringBootApplication(scanBasePackages = {&quot;com.factelcore.*&quot;,&quot;uy.com.antel.fact.*&quot;})
  3. @EnableJpaRepositories(&quot;com.factelcore.repository&quot;)
  4. public class ApplicationInitializer extends SpringBootServletInitializer {
  5. public static void main(String[] args){
  6. SpringApplication.run(ApplicationInitializer.class,args);
  7. }
  8. @Override
  9. protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
  10. return application.sources(applicationClass);
  11. }
  12. private static Class&lt;ApplicationInitializer&gt; applicationClass = ApplicationInitializer.class;
  13. }

By doing this I made sure I had a spring context in the api, which I could work with. When I start Spring from here I scan all the api and core files, performing the appropriate configuration of the beans.

After doing this, I needed to capture the context to recover the beans that are defined in the core, so I could work with the @Service class defined in the core. For this I created the following class:

> Api - AppContextUtil.java

  1. @Component
  2. public class AppContextUtil implements ApplicationContextAware {
  3. @Autowired
  4. private WebApplicationContext context;
  5. private static ApplicationContext appContext;
  6. @PostConstruct
  7. public void init() {
  8. if (context != null) {
  9. setApplicationContext(context);
  10. }
  11. }
  12. @Override
  13. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  14. AppContextUtil.appContext = applicationContext;
  15. }
  16. public static ApplicationContext getContext() {
  17. return appContext;
  18. }
  19. }

Once this was done, using the SolicitudApiServiceImpl I was able to do the following to invoke the bean I needed at a certain time:

Api - SolicitudApiServiceImpl.java

  1. ApplicationContext cont = AppContextUtil.getContext();
  2. SolicitudInformacionService solInfServ = cont.getBean(SolicitudInformacionService.class);

I don't know if this is the ideal way to do this, but in my case it worked for me, if there is someone who has a better way to do it feel free to tell me so I can improve the code. Thank you very much!

huangapple
  • 本文由 发表于 2020年10月17日 03:27:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/64395245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定