3
\$\begingroup\$

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() {
                // Database has a newly inserted (and committed) image data here. asynceImageConvertService will select and update it.
                // fnSaveObject function should run in current transaction.
                asyncImageConvertService.processImage(image.getId(), file);
            }
        });

        imageMapper.insert(image); // image's id will be generated here.
        fnSaveObject.run();  // image's id should exists here.
    }
}

It is called from the following code:

uploadService.uploadImage(
                profileImage,
                "/user/" + user.getId() + "/" + profileImage.getUrl(),
                () -> userMapper.insertImage(user, profileImage) // generated image's id will be applied.
);

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?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.