bigjel
bigjel

Reputation: 57

Inject specific beans as parameters in function with multiple parameters

I understand that i can use @Autowired to inject a bean in a class.

Now i get curious:: I don't want to have a private attribute with @Autowired. I have a function in my controller and i want to inject bean as parameters directely in the function. I got an error saying that file and token are not beans.

Is there a way to autowire or inject just the beans i need as parameters ?

@Controller
public class SpinalToolboxWebController {

    /*@Autowired
    private FileOperationsService fileOperationsService;


    @Autowired
    private Comparator<String> comparator;

    @Autowired
    private ServerResponse serverResponse;

    @Autowired
    private SoftwareCommunicationService softwareCommunicationService;

    @Autowired
    private StringBuffer stringBuffer;

    @Autowired
    private UserEnvironmentService userEnvironmentService;*/


    @Autowired
    @RequestMapping(value="/upload", method = RequestMethod.POST, produces="application/json")
    public  @ResponseBody
    ServerResponse handleUploadedFiles(@RequestParam(value = "file") MultipartFile file,
                                       @RequestParam(value="token") String token, 
                                       SoftwareCommunicationService softwareCommunicationService,
                                       FileOperationsService fileOperationsService, 
                                       ServerResponse serverResponse )throws IOException {

        System.out.println("Passing throught upload controller");

        if(!fileOperationsService.isUploadedFileExtensionAllowed(file.getOriginalFilename()))
        {
            serverResponse.setUndefinedResponse();
            return serverResponse;
        }

        if(fileOperationsService.uploadFile(file, token)){
            serverResponse.setResponse(file, softwareCommunicationService.generateRawAndHeader(file));
        }
        else{
            serverResponse.setUndefinedResponse();
        }
        return serverResponse;
    }

}

Upvotes: 2

Views: 2900

Answers (1)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279990

As a built-in feature, no. You can't do what you are suggesting.

Spring, however, provides the tools to program this functionality yourself. You'll need to come up with a marker annotation type. Something like @MethodBean. You can annotate the handler method parameters you want injected from the ApplicationContext. You'll then need to write a class that extends HandlerMethodArgumentResolver and which looks for this annotation. You have to add an @Autowired WebApplicationContext field from which to get the beans and supply them to the method.

You'd then register this bean as part of the HandlerMethodArgumentResolvers of our MVC stack.

When Spring determines that it has to invoke the handler method in your example, which now looks like this

@RequestMapping(value="/upload", method = RequestMethod.POST, produces="application/json")
public @ResponseBody
ServerResponse handleUploadedFiles(@RequestParam(value = "file") MultipartFile file,
                                   @RequestParam(value="token") String token, 
                                   @MethodBean SoftwareCommunicationService softwareCommunicationService,
                                   @MethodBean FileOperationsService fileOperationsService, 
                                   @MethodBean ServerResponse serverResponse )throws IOException {

it will use the appropriate HandlerMethodArgumentResolver to resolve an argument for each of the parameters.

For the @MethodBean annotated parameters, it will find your custom implementation, look for a bean of the type of the parameter in the injected WebApplicationContext, and provide it as an argument.

Upvotes: 3

Related Questions