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.
Service through which I receive the rest call and communicate with the core.
Service in core
Dependence on the api to the core
Spring Boot initializer, when you start the ear in wildfly, this project starts automatically and makes the relevant settings.
I would be grateful if someone could guide me in solving this problem, thank you in advance.
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.
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:
public class Main {
private static ConfigurableApplicationContext context;
public static void main(String[] args) {
context = SpringApplication.run(MyApplication.class, args);
}
public static ConfigurableApplicationContext getContext() {
return context;
}
}
public class SolicitudApiServicelmpl {
private ConfigurableApplicationContext context = Main.getContext();
private SolicitudInformacionService solInfServ = context.getBean(SolicitudInformacionService.class);
// Now `solInfServ` is not null anymore.
// ...
}
@Component
public class SomeClassWithSpringContext {
@Autowired private SolicitudApiServicelmpl solicitudService;
// with this @Autowired should work in the `service` instance.
}
or with the context instance:
@Component
public class SomeClassWithSpringContext {
@Autowired private WebApplicationContext context;
public void someMethodOrSomewhere() {
SolicitudApiServicelmpl service = context.getBean(SolicitudApiServicelmpl.class);
// with this @Autowired should work in the `service` instance.
}
}
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
@Order(Ordered.HIGHEST_PRECEDENCE)
@SpringBootApplication(scanBasePackages = {"com.factelcore.*","uy.com.antel.fact.*"})
@EnableJpaRepositories("com.factelcore.repository")
public class ApplicationInitializer extends SpringBootServletInitializer {
public static void main(String[] args){
SpringApplication.run(ApplicationInitializer.class,args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
private static Class<ApplicationInitializer> applicationClass = ApplicationInitializer.class;
}
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
@Component
public class AppContextUtil implements ApplicationContextAware {
@Autowired
private WebApplicationContext context;
private static ApplicationContext appContext;
@PostConstruct
public void init() {
if (context != null) {
setApplicationContext(context);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
AppContextUtil.appContext = applicationContext;
}
public static ApplicationContext getContext() {
return appContext;
}
}
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
ApplicationContext cont = AppContextUtil.getContext();
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!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.