In Spring MVC, Inside a Controller class, the method annotated with #RequestMapping annotation are allowed to have Flexible Method Signature.
If I want to do something like this with my own custom annotation, Can somebody give me some pointers for the same.
Thanks in Advance.
Spring MVC has a lot of features in that regard so it might be easier to look elsewhere as a starting point. The new messaging abstraction that was introduced in Spring 4 has similar features.
Look at #MessageMapping which allows you to build a flexible signature against a Message instance. You could for instance inject a header of the message
public void foo(#Header("myHeader") int myHeader)
Or you could validate that the payload against a Validator
public void bar(#Payload #Validated Order order)
The core of the infrastructure is located in InvocableHandlerMethod which is going to invoke a java.lang.reflect.Method you have provided on a given bean instance based on an incoming Message and additional parameters you may provide (see public final Object invoke(Message<?> message, Object... providedArgs)
To create that instance, you need to provide a set of HandlerMethodArgumentResolver. Each HandlerMethodArgumentResolver is responsible to handle a method parameter. In short, that's basically going to provide you a MethodParameter instance (i.e. a reference to a parameter of the method you want to handle, such as the annotated order in the last example) and you're going to tell if you support it or not and when you do, handle that parameter so that the right value is injected. For the header example, the implementation looks for a header with the name on the annotation. Simple!
A set of default resolvers are created for example in SimpAnnotationMethodMessageHandler (look at initArgumentResolvers). That's going to show you the kind of parameters you can inject there by default. By extending that list (or providing custom instances) you can augment what the user can use in the method signature.
In Spring 4.1, we rely on this infrastructure to provide JMS listener annotated endpoints and those endpoints may have a flexible signature as well. It's actually already implemented so you may want to have a look to that for yet another example.
Related
I have a question on Java Syntax on lambda expressions and the java.util.function.Function Object. Also probably Spring Dependency Injection. It is an idiom that I don't know and I hope somebody can explain it to me. I know (probably only the basics) about that idiom of generic#FunctionalInterface(s) and "implementations" through lambda expressions. This use-case seems similar, but still different.
In the example, the Function<T,R>-Object is the Type of a parameter of a method of a configuration class with a parameter name. The argument is the lambda expression config -> tokenStore.
But please look at the information provided below. Here are my questions.
What config is passed as the argument? There is no "config" symbol there. So I guess it is injected by the Spring IoC Container.
And what it obviously returns is the symbol tokenStore that is bound to an org.axonframework.eventhandling.tokenstore.TokenStore Instance created by theJpaTokenStore#build method. There is no connection to the config argument. Or is there?
To sum it up: Just "Why?" Why are you passing a lambda expression where there is no obvious (to me) connection between the argument and the return value and why are you passing a Function-placeholder to an Interface-method - how do you call it... the head of the method? Ultimately: What is that doing because to someone like me who obviously doesn't know the idiom it looks like the answer is: nothing ?
So, there is this example on how to configure a TokenStore from the Axon Framework and I would like to understand how it works:
public class AxonConfig {
// ...
public void registerTokenStore(EventProcessingConfigurer processingConfigurer) {
TokenStore tokenStore = JpaTokenStore.builder()
// …
.build();
processingConfigurer.registerTokenStore(config -> tokenStore);
}
}
source: https://docs.axoniq.io/reference-guide/axon-framework/events/event-processors/streaming#token-store
And here is the source code for the EventProcessingConfigurer#registerTokenStore (GitHub) method.
public interface EventProcessingConfigurer {
// ...
EventProcessingConfigurer registerTokenStore(Function<Configuration, TokenStore> tokenStore);
// ...
}
Incidentally, can I pass in an argument for the code block to tell the forum software which language it is?
Let me provide you some insights here, #vonSpots!
Question 1
The config symbol stands for the input parameter of the Function. You can name it whatever you like. Note the type of the configuration method, which expects a Function<Configuration, TokenStore>. The first generic in there describes the input parameter of the Function, thus a Configuration instance. The second generic describes the return value of the Function, which should be a TokenStore instance.
By using Java's lambda notation of [input] -> [output], ending up with something called config seems feasible given the input type. The component in charge of providing that config instance, is the framework itself.
You can see this within Axon Framework's configuration module. Lastly, it's worthwhile to note that Axon Framework does not necessitate the use of Spring at all. So, setting the config instance is not originating from Spring.
Question 2
In the provided sample, there's no connection between the input and the output. However, Axon Framework defaults to providing the entire Configuration object so that the user is able to retrieve Axon components from it to construct other infrastructure components.
An example of where this would be useful with the JpaTokenStore, is when you need to set the Serializer. Axon Framework will set the Serializer up within the Configuration. Hence, you can retrieve it from Axon's configuration to construct your component.
Question 3
Because Axon Framework does its own wiring of all components. You can integrate it with Spring if you like, but it does not rely on it at all. Thus, in the face of a "pure" Java configuration, you need to have some collecting component, the Configuration, to retrieve everything from. You could almost see it as the Application Context from Spring.
Furthermore, Axon Framework chooses to have users register lambdas instead of concrete objects to ensure components are constructed and wired in the right order.
Axon Framework has many moving components, with objects like the CommandBus, EventProcessors, TokenStores, and DeadlineManager, not forgetting to mention the Message Handling Components users wire into it themselves. By having end users provide a lambda, the framework can decide when to invoke the lambda.
This allows the framework to ensure all required components are in place before a, in your sample, TrackingEventProcessor can utilize the TokenStore.
My questions are about the lifecycle of controllers in the Play framework for Java, if the controllers are stateful instances or stateless with static methods, and how to use dependency injection in the controller code.
Is each web request handled by a new instance of a Play controller class, i.e. can a controller store state in fields such as services injected into the controller constructor?
(where in the documentation is it explained?)
Has the Play framework changed since earlier versions (and if so, at what version?) regarding if controllers are stateful instances or stateless controllers with static methods?
Where can you see code examples about how the framework injects services into a controller instance when stateful controller is used and example of how to inject services into a static controller method?
Regarding the latter, i.e. injection into a static method I suppose that would either have to be a parameter to the method which the frameworks will add, or if not possible you maybe instead will have to use a service locator from within the method e.g. instantiate a Guice module class and then use "injector.getInstance" from within the static controller method.
This subject is touched in the section "Dependency injecting controllers" at the following page:
https://www.playframework.com/documentation/2.4.x/JavaDependencyInjection
However, it does not show with code how to actually inject services into a controller instance (but probably the same way as other "components" i.e. with #Inject annotation) and certainly it does not currently show how to use DI with a static controller method.
I am confused about these things because I have not found documentation being clear about my questions, and I have also read in a Play book (from 2013) that the controller methods should be programmed as stateless and the controller methods should be static.
However, when now using activator for generating a Play application for Java with the latest Play version (2.4.6) I can see that the generated Controller method (Application.index) is NOT static.
Also, at the following documentation page, the controller method is NOT static:
https://www.playframework.com/documentation/2.4.x/JavaActions
This is confusing, and since it is VERY fundamental to understand whether or not each request is handled by a Controller instance or not (i.e. if state can be used) I think this should be better documented at the page about Controller/Actions than the current documentation (the above linked page) which is not explaining it.
The documentation about dependency injection touches the subject about static and non-static methods at the section "Dependency injecting controllers" mentioning "static routes generator" but I think it should be better explained including code examples.
If someone in the Play team is reading this question, then please add some information to the above linked pages, for example please do mention (if my understanding is correct) that in previous versions of Play the controller methods were static and for those versions you should never store state in fields, but in later versions (beginning from version x?) each request is handled by an instance of a controller and can therefore use state (e.g. constructor parameters injected by the framework).
Please also provide code examples about injection used with static controller methods and injection into stateful controller instances with one instance per request.
The section "Component lifecycle" in the dependency injection page only mentions "components" but I think it should also be explicit about the controller lifecycle and its injection, since it is such a fundamental and important knowledge to communicate clearly to all developers to avoid bugs caused by misunderstandings about being stateful or not.
Is each web request handled by a new instance of a Play controller class, i.e. can a controller store state in fields such as services injected into the controller constructor? (where in the documentation is it explained?)
As far as I can tell, controllers are by default singleton objects. This is not clearly documented, but it is implied that controller instances are reused. See the migration guide for Playframework 2.4:
The injected routes generator also supports the # operator on routes, but it has a slightly different meaning (since everything is injected), if you prefix a controller with #, instead of that controller being directly injected, a JSR 330 Provider for that controller will be injected. This can be used, for example, to eliminate circular dependency issues, or if you want a new action instantiated per request.
Also, check this commend made by James Roper (Play core committer) about if controllers are singleton or not:
Not really - if using Guice, each time the controller is injected into something, a new instance will be created by default. That said, the router is a singleton, and so by association, the controllers it invokes are singleton. But if you inject a controller somewhere else, it will be instantiated newly for that component.
This suggests that the default is to reuse controller instances when responding to requests and, if you want a new action per request, you need to use the syntax described in the migration guide. But... since I'm more inclined to prove and try things instead of just believe, I've created a simple controller to check that statement:
package controllers
import play.api._
import play.api.mvc._
class Application extends Controller {
def index = Action {
println(this)
Ok(views.html.index("Your new application is ready."))
}
}
Doing multiple requests to this action prints the same object identity for all the requests made. But, if I use the # operator on my routes, I start to get different identities for each request. So, yes, controllers are (kind of) singletons by default.
Has the Play framework changed since earlier versions (and if so, at what version?) regarding if controllers are stateful instances or stateless controllers with static methods?
By default, Play had always advocated stateless controllers, as you can see at the project homepage:
Play is based on a lightweight, stateless, web-friendly architecture.
That had not changed. So, you should not use controllers' fields/properties to keep data that changes over time/requests. Instead, just use controllers' fields/properties to keep a reference to other components/services that are also stateless.
Where can you see code examples about how the framework injects services into a controller instance when stateful controller is used and example of how to inject services into a static controller method?
Regarding code examples, Lightbend templates repository is the place to go. Here are some examples that use dependency injection at the controllers level:
https://github.com/adrianhurt/play-api-rest-seed
https://github.com/knoldus/playing-reactive-mongo
https://github.com/KyleU/boilerplay
Dependency Injection with static methods is not supported, and that is why Playframework stills offers old apis to use with static methods. The rule of thumb here is: choose between DI and static methods. Trying to use both will just bring complexity to your application.
Ok, thank you marcospereira.
I have now also confirmed that you indeed get different instances (different toString values which can be printed/logged in a controller method) of the controller for each request.
For those who are interested, the solution (to get different instances of controller class for each request) is to use for example the following:
GET / #controllers.Application.index()
instead of the following:
GET / controllers.Application.index()
in the file "conf/routes"
AND to also use the following:
routesGenerator := InjectedRoutesGenerator
instead of the following:
routesGenerator := StaticRoutesGenerator
in the file "build.sbt"
Regarding the statement that Play has a "stateless" architecture:
Maybe I am wrong, but as far as I understand the terminology, the "stateless" means that the web server does not store any state between requests?
The word "stateless" does not mean that a controller instance can not use fields, e.g. injected into the constructor.
If an injected object is stored as a field in a controller, then that field is a "state" of the controller.
Therefore, even if you use "InjectedRoutesGenerator" and the "#" prefix to get "stateful" controller instances, that injected "state" is only stored within one request, so you can still say that the framework itself is "stateless" since the server does not store any state between multiple requests.
Please do correct me if I have misunderstood something about Play being stateless.
public ModelAndView loginPage(HttpServletRequest request, Locale locale) {}
As you know, Spring injects HttpServletRequest and Locale into the method. I want to know
how is it done behind the curtains ? My guess is, there is a data converter system working behind
that takes http request headers and body data and fill them into the suitable classes that are given
in arguments by the coder. Am I right ?
When working with Spring MVC there are multiple parts moving to solve the problem of mapping HandlerMapping and execution HandlerAdapter.
Each #Controller is scanned for #RequestMapping annotated methods, the methods are mapped to URLs based on the metadata available in the #RequestMapping annotation, this is done by the RequestMappingHandlerMapping class.
When a request comes in the specific method is matched on the incoming request. This selected method is passed the RequestMappingHandlerAdapter which consults all method arguments. The actual handling of the method argument is left to different HandlerMethodArgumentResolver implementations (you could also implement your own).
The same happens for the return value of your method although that is delegated to a HandlerMethodReturnValueHandler.
Yes, you're right. In short, there is a single entry point into the application (there may be more than one entry point) that routes incoming traffic, passing incoming data to methods as parameters. This is known as the front controller pattern.
Spring's DispatcherServlet is an implementation of the front controller pattern. The Spring reference details the pattern as followed in Spring, and the pattern is listed among the core Java EE patterns.
I am using Struts 2 and Spring autowiring. Right now, the default strategy is set to by-name, but usually we use the constructor and the fallback works to autowire in properties when only one implementing class is available.
There is one property however that I'd like to wire into an action class that has several implementing classes, so I made the Action a java bean, with the properties as fields that can be set. Unfortunately, the only ways that these will be used (apparently) is if they have a public getter/setter, which also exposes them to the type converter at request time. In other words, if a client adds their name to the request as form fields or parameters, Struts will attempt to write those values to them.
So my question is, is it actually possible to use by-name autowiring without exposing properties like that (which may or may not be a security hazard), or am I better off just using XML and defining the Action as an object with scope prototype?
I did eventually track down the documentation for the ParametersInterceptor which actually lists three ways you can limit what parameters are set by the interceptor.
Configuring excludeParams in the parameter configuration, which is a global regex which applies to all actions (not what I want, also possibly deprecated as it is no longer described in the most recent class docs).
Setting excludeMethods (does the same as the previous, the preferred method for global excludes)
Implementing ParameterNameAware, which is the closest to what I wanted. Here you can whitelist what parameters are used.
In the end, defining the action as a prototype object in the normal Spring configuration seemed to be the most prudent. Letting the action manage what parameters it has means another place where parameters need to be explicitly white listed every time a change is made.
With Spring MVC, it's easy to express a concept like "A user is submitting the form if they use POST or if they include the 'isSubmit' parameter." You'd just extend SimpleFormController and override the isFormSubmission method.
However, Spring MVC now uses these neat annotations like #RequestMapping to handle requests. #RequestMapping has an obvious filter for whether somebody used a GET or a POST, but I don't see any inherent support for all of the useful logic SimpleFormController provided. Is it still available to me with annotations?
So, after a bit of investigation, there are in fact a couple of ways to handle this situation.
The first way is to go ahead and use a SimpleFormController with with #RequestMapping annotation at the class level. A lesser-known but pretty cool property of #RequestMapping is that it knows perfectly well how to deal with the classes that implement Spring's Controller interface. The only downside here is that I'm still using the old MVC interfaces and classes, and they're going to be deprecated in Spring 3.0.
The second way was pointed out by kgiannakakis above. Simply create a #RequestMapping method for every way that the submit can be called, and have them all just call a single submit method, either in a constructor-chaining style or with some private method. Simple and easy to understand. Thanks, kgiannakakis!
Copying from here:
Path mappings can be narrowed through parameter conditions: a sequence of
"myParam=myValue" style expressions, with a request only mapped if each such
parameter is found to have the given value. "myParam" style expressions are
also supported, with such parameters having to be present in the request
(allowed to have any value). Finally, "!myParam" style expressions indicate
that the specified parameter is not supposed to be present in the request.
You can only use the RequestMapping options to define the desired functionality. The Annotations Controller doesn't implement any interface to work with.
Here is one example of using Path mappings:
#RequestMapping(params = "formAction=APPROVE", method = RequestMethod.POST)
public String myMethod ()....
This method will only be called then for POSTs where there is a field named "formAction" with a value of "APPROVE".
The other answers listed work fine for a method annotated with #RequestMapping.
However, if you want to achieve the same thing on a method annotated with #InitBinder, you can simply do this:
#InitBinder
public void initBinder(HttpServletRequest request) {
if ("POST".equals(request.getMethod()){
//Do something
}
}