I have an Entity-Repo-Service Spring Boot framework to simply visualize data in JFreeChart. Admitting that this is a common problem, but I've spent too much time reading and trying solutions from the big thread Why is my Spring @Autowired field null? that it may be more efficient to ask for help. I'm still learning Spring Boot, so I must have not understood the solutions thoroughly or overlooked some key points.
Repo:
package com.tool.logsview.repository;
import ...
@Repository
@ComponentScan(basePackages = {"com.tool.logsview"})
public interface LogRepository extends JpaRepository<Log, Long> {
@Override
List<Log> findAll();
List<Log> findByDept(String dept);
}
Service:
package com.tool.logsview.service;
import ...
@Service
public class LogServiceImp implements LogService{
@Autowired
private LogRepository logRepository;
@Override
public List<Log> findByDept(String dept) {
return logRepository.findByDept(dept);
}
}
Controller where I integrate with JFreeChart
package com.tool.logsview.controller;
import ...
@Component
@Configurable
@ComponentScan(basePackages = {"com.tool.logsview"})
public class GanttChartWithData extends JFrame {
@Autowired
LogServiceImp logServiceImp; // <- null
public GanttChartWithData(final String title) {
super(title);
// ...
}
private @NotNull IntervalCategoryDataset createDataset() {
List<Log> demoDept = logServiceImp.findByDept("Demo"); // <- npe, the only use of logServiceImp in this class
// ...
}
public static void main(final String[] args) {
// ... JFreeChart
}
}
I tried:
- Use annotation and no
new
- Add annotations
@Component
/@Service
/@Controller
for classGanttChartWithData
- Solution Changing to @Service, then using construction injections.
package com.tool.logsview.controller;
import ...
@Service
public class GanttChartWithData extends JFrame {
private static
LogRepository logRepository;
@Autowired
public GanttChartWithData(final String title, LogRepository logRepository) {
super(title);
// ...
this.logRepository = logRepository;
}
// Creates a sample dataset for a Gantt chart.
private @NotNull IntervalCategoryDataset createDataset() {
// ...
List<Log> demoDept = logRepository.findByDeptAndUsernameOrderByUsernameAsc("Demo", "personA");
}
public static void main(final String[] args) {
final GanttChartWithData demo = new GanttChartWithData("Gantt Chart Demo", logRepository);
}
}
Note that this works completely fine, but I don't want to bring a junk of code to Application
@SpringBootApplication
public class LogsviewApplication {
@Autowired
private LogRepository logRepository; // <- not null
...}
At this point, I'm completely confused. Even to a point that I don't know why we should go Repo -> Service -> Controller while I used Repo directly and it works fine (In the Application, I used Repo instead of ServiceImplementation).
Any enlightenment is much appreciated!
UPDATE:
- My use of Application Context following this guide:
package com.tool.logsview.misc;
import ...
@Controller
public class Dummy {
@RequestMapping("/dummy")
@ResponseBody
public List<Log> dummy() {
LogServiceImp logServiceImp = ApplicationContextHolder.getContext().getBean(LogServiceImp.class);
return logServiceImp.fetchLogList();
}
}
This proves that Application Context works, but I don't need a web Controller. I want to call logServiceImp for business service. Thus, attempting to change it to
package com.tool.logsview.misc;
import ...
@Service
public class Dummy {
public Dummy() { }
@Autowired
static LogServiceImp logServiceImp1; // null - the same problem
public static void main(String[] args) {
LogServiceImp logServiceImp = ApplicationContextHolder.getContext().getBean(LogServiceImp.class); // application context but still null
System.out.println(logServiceImp.fetchLogList());
System.out.println(logServiceImp1.fetchLogList());
}
}
Very likely misunderstand the whole IOC concept?
Context if it helps: At first, it was intended to visualize data on a browser, hence the Controller structure, but I switch to JFreeChart java lib to run with Swing, so I don't need @Controller and @RequestMapping. As @Georgy Gobozov points out, I may not need a Controller. But I do need @Service to do visualizing services.