How come application.properties will work in a RestController, but not in a service class?
//application.properties
test=test
Works Perfect!
#RestController
public class invitecontroller {
#Autowired inviteconfig inviteconfig;
#PostMapping("/v1/invite")
public void invite(#RequestBody XXX XXX) {
System.out.println(inviteconfig);
}
}
Returns "Null"
#Service
public class inviteservice {
#Autowired inviteconfig inviteconfig;
public void invite() {
System.out.println(inviteconfig);
}
}
#Configuration
#Data
public class inviteconfig {
private String test;
}
The inviteservice class is not configured for Spring IoC (Inversion of Control) as a bean, so Spring will not handle the inviteservice class lifecycle. In this case, #Autowired is useless.
To fix this try to add #Component annotation to invitesevice, to declare it as a component:
#Component
public class inviteservice {
#Autowired inviteconfig inviteconfig;
public void invite() {
System.out.println(inviteconfig);
}
}
In the case of the controller, with #RestController, Spring will recognize your class as a Spring component.
Finally, don't forget to inject inviteservice using Spring IoC (using #Autowired annotation, or other means)
inviteservice class should be annotated with #Component or #Service
#Component
public class inviteservice {
...
Related
I've already read these questions and none of them worked:
Spring boot MVC - Unable to Autowire Repository in the service class
Why can't #Autowired a JPA repository - Spring boot + JPA
JpaRepository getting Null at service class
And also this one: https://www.baeldung.com/spring-autowired-field-null
Unfortunately, none of them worked.
What I have is:
Service interface:
#Service
public interface DayTradeService {
public List<DayTrade> getDayTrades(List<NotaDeCorretagem> corretagens);
}
Service Implementation:
public class DayTradeServiceImpl implements DayTradeService {
#Autowired
private DayTradeRepository dayTradeRepository;
#Override
public List<DayTrade> getDayTrades(List<NotaDeCorretagem> corretagens) {
// Several lines of code and some of them is trying to use dayTradeRepository.
}
}
My DayTradeRepository:
#Repository
public interface DayTradeRepository extends JpaRepository<DayTrade, Integer> {}
Inside my DayTradeController (annotated with #Controller), I can use a dayTradeRepository with #Autowired. But inside a service class, I cannot use. I get this message:
Cannot invoke "meca.irpf.Repositories.DayTradeRepository.getDayTrades()" because "this.dayTradeRepository" is null"
How can I make it possible?
EDIT after I accepted Nikita's answer:
I didn't post the Controller code, but it didn't have the #Autowired for the service class DayTradeServiceImpl. That was the point I was missing. After Nikita pointing that, I could solve the problem.
You not need create new object. You have to call like this:
#Controller
#RequestMapping("/test")
public class TestController {
#Autowired
private DayTradeServiceImpl dayTradeService;
#GetMapping(value = "/get")
public void getTrades() {
dayTradeService.getDayTrades(...);
}
}
And set annotation #Service for DayTradeServiceImpl.
#Service
public class DayTradeServiceImpl implements DayTradeService {
#Autowired
private DayTradeRepository dayTradeRepository;
#Override
public List<DayTrade> getDayTrades(List<NotaDeCorretagem> corretagens) {
// Several lines of code and some of them is trying to use dayTradeRepository.
}
}
Spring framework use inversion of control, which has container for beans. For detect beans use annotation like: #Service, #Component, #Repository.
I have a rest controller like this :
#Slf4j
#RestController
#RequestMapping(...)
public class MyController {
private MyService service;
public MyController(MyService service){
this.service = service;
}
And the service class is a component :
#Component
public class MyService{
...
}
And when I run the program, the service field is correctly injected. But how is it injected (there is no autowired annotation neither on filed ni on constructor) ?.
I am using SpringBoot 2.0.
From Spring 4.3 release. According to the documentation (https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-spring-beans-and-dependency-injection), if a bean has single constructor, #Autowired annotation can be omitted.
If a bean has one constructor, you can omit the #Autowired, as shown in the following example:
#Service
public class DatabaseAccountService implements AccountService {
private final RiskAssessor riskAssessor;
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
Service Component object is not loaded in Spring Batch processor.But which is working fine with Spring Testing.Please help me to find the solution for this.
public class PersonJobProcessor implements ItemProcessor<Person,Person> {
#Autowired
PersonService service;
#Override
public Person process(final Person person) throws Exception {
//user service variable here
}
}
Error Message:-
Action:Consider defining a bean of type 'PersonService' in your configuration.
Below configuration is working fine
#SpringBootTest
#RunWith(SpringRunner.class)
public class PersonServiceTest {
#Autowired
PersonService service;
public void testmethod(){
service.method();// works without issues
}
}
Looks like missing SpringContext inside PersonJobProcessor. Did you add #Component on this class?
Want put a class in a HashMap. For that I have created a Bean with #Service. This is it:
#Service
public class ServiceManagerImpl implements ServiceManager {
#Override
public void registerService() {
// registerService will put this in the HashMap!
dispatcher.registerService("serviceList", getServiceListImpl());
}
#Bean
public BusinessService getServiceListImpl() {
return new ServiceListManager();
}
}
Is this the right way to make something like this?
Move your bean definition from a class annotated with #Service to a configuration class annotated with #Configuration (or at least move to your main class which has #SpringBootApplication annotation, if you have). Then Autowire that bean here in the Service class. `
#Autowired BusinessService businessService
take a look here Where to put #Bean in Spring Boot?
I have several classes in a Spring Boot project, some work with #Autowired, some do not. Here my code follows:
Application.java (#Autowired works):
package com.example.myproject;
#ComponentScan(basePackages = {"com.example.myproject"})
#Configuration
#EnableAutoConfiguration
#EnableJpaRepositories(basePackages = "com.example.myproject.repository")
#PropertySource({"classpath:db.properties", "classpath:soap.properties"})
public class Application {
#Autowired
private Environment environment;
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
#Bean
public SOAPConfiguration soapConfiguration() {
SOAPConfiguration SOAPConfiguration = new SOAPConfiguration();
SOAPConfiguration.setUsername(environment.getProperty("SOAP.username"));
SOAPConfiguration.setPassword(environment.getProperty("SOAP.password"));
SOAPConfiguration.setUrl(environment.getProperty("SOAP.root"));
return SOAPConfiguration;
}
HomeController (#Autowired works):
package com.example.myproject.controller;
#Controller
class HomeController {
#Resource
MyRepository myRepository;
MyService (#Autowired does not work):
package com.example.myproject.service;
#Service
public class MyServiceImpl implements MyService {
#Autowired
public SOAPConfiguration soapConfiguration; // is null
private void init() {
log = LogFactory.getLog(MyServiceImpl.class);
log.info("starting init, soapConfiguration: " + soapConfiguration);
url = soapConfiguration.getUrl(); // booom -> NullPointerException
I do not get the SOAPConfiguration but my application breaks with a null pointer exception when I try to access it.
I have already read many Threads here and googled around, but did not find a solution yet. I tried to deliver all necessary information, please let me know if anything misses.
I guess you call init() before the autowiring takes place. Annotate init() with #PostConstruct to make it call automatically after all the spring autowiring.
EDIT: after seeing your comment, I guess you are creating it using new MyServiceImpl(). This takes away the control of the MyServiceImpl from Spring and gives it to you. Autowiring won't work in those case
Did you created a bean for the class SOAPConfiguration in any of your configuration classes? If you want to autowire a class in your project, you need to create a bean for it. For example,
#Configuration
public class SomeConfiguration{
#Bean
public SOAPConfiguration createSOAPConfiguration(){
return new SOAPConfiguration();
}
}
public class SomeOtherClass{
#Autowired
private SOAPConfiguration soapConfiguration;
}