First, sorry for my poor English. I don't usually use it.
Here is the working code for my spring service:
@Service
public class UploadService {
@Inject
@Qualifier("session")
Session session;
@Inject
AsyncImageConvertService asyncImageConvertService;
@Value("${aws.bucket-name}")
String awsBucketName;
@Inject
AmazonS3 amazonS3;
@Inject
ImageMapper imageMapper;
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public void uploadImage(Image image, String url, Runnable fnSaveObject) {
File file = new File(System.getProperty("java.io.tmpdir"), image.getUrl());
image.setUrl(url);
image.setCreator(session.getUser());
PutObjectRequest request = new PutObjectRequest(awsBucketName, image.getUrl(), file);
request.setCannedAcl(CannedAccessControlList.PublicRead);
amazonS3.putObject(request);
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
public void afterCommit() {
asyncImageConvertService.processImage(image.getId(), file);
}
});
imageMapper.insert(image);
fnSaveObject.run();
}
}
It is called from the following code:
uploadService.uploadImage(
profileImage,
"/user/" + user.getId() + "/" + profileImage.getUrl(),
() -> userMapper.insertImage(user, profileImage)
);
The Runnable functional interface will run in transaction and invoke async service method after transaction committed.
*Mapper is injected instance also, via spring-mybatis.
This code looks like it's working well, but I'm afraid it's not safe.
Is it safe to use functional interface arguments in methods of services injected via Spring?