I'm using Spring Boot to write server application.
Most of the time, I write all business logic inside services, where I use @Autowired
to access repositories and other services.
However, sometimes I want to access certain service or property from @Entity
class, which cannot use @Autowired
.
For instance, I have an entity that should be able to serialize itself to JSON. In JSON, it should have imageUrl field, which contains of image name (stored in database and as a property in the @Entity
class) and base url, which is only available in application.properties. This means that I have to use @Value
annotation inside @Entity
class, but it doesn't work that way.
So I create a service which looks like this:
@Service
public class FilesService {
private static FilesService instance;
@PostConstruct
public void init() {
FilesService.instance = this;
}
public static FilesService getInstance() {
return instance;
}
@Value("${files.path}")
String filesPath;
@Value("${files.url}")
String filesUrl;
public String saveFile(MultipartFile file) throws IOException {
if (file == null || file.isEmpty()) {
return null;
}
String filename = UUID.randomUUID().toString();
file.transferTo(new File(filesPath + filename));
return filename;
}
public String getFileUrl(String filename) {
if (filename == null || filename.length() == 0) {
return null;
}
return filesUrl + filename;
}
}
And then inside the @Entity
class I write the following code:
@JsonProperty
public String getImageUrl() {
return FilesService.getInstance().getFileUrl(imageName);
}
This works, but it doesn't look right. Moreover, I concern whether this can lead to some side effects if used with less trivial @Service
classes or @Repository
classes.
What is the correct way to use @Repository
and @Service
classes from @Entity
classes or any other non-@Component
classes (classes not managed by Spring)?