1

I was looking at Spring MVC's documentation and I saw a mention about if your controller implemented an interface and was proxied you'd have to put the annotations on your interface or proxy by target class since otherwise the annotations wouldn't be picked up (the proxy wouldn't contain the annotations since it would be another class wrapping your bean via the exposed interface if it wasn't a subclass of the controller class).

However, in my experience controllers are supposed to be the simplest things out there - get the web-based inputs (formatting/creating the "model"), decide on the flow control to execute by delegating to business service layer interfaces/classes (controlling based on the state of the model), and then sending the model to the view layer to compose the resulting view.

Can anyone provide a really good use case of why you'd want to proxy a controller? Service layer methods, sure, but a controller?

tereško
  • 58,060
  • 25
  • 98
  • 150
MetroidFan2002
  • 29,217
  • 16
  • 62
  • 80

1 Answers1

0

The reason you would proxy a controller is to do Proxy AOP.

Proxy AOP used to only work with dynamic proxies which will only proxy interfaces. However I think Spring now supports CGLIB proxying.

Personally I avoid the proxy based AOP altogether by using real compile time AspectJ which Spring also supports.

Why would you want to AOP your controller? To avoid boilerplate code such as: security, input sanitization, logging (all of which I do on my request controllers).

EDIT: I meant to augment this answer last night as I knew you would have a followup.

Yes TODAY with requests you can do a lot of AOP with servlet filters and interceptors and I do have a majority of the cross cutting code in filters but that was not the case earlier when Spring first introduced its AnnotationMethodHandler (~2.5) compared to today's 3.0 AnnotationMethodHandler > 3.0 (notice the plethora of additional strategy components via the setters).

A real current example of why you might want to use AOP is to use Springs Security Annotations (ie @PreAuthorize) in your request controller instead of having to go put an interceptor in an XML file (See this question and my answer). Or perhaps you don't need a service layer and want to use @Transaction.

The other reason I use AOP in my controllers is that its more declarative and will work when I unit test calling the method directly (granted I don't use proxy but AspectJ). In fact I use AspectJ similar to Python's Decorator to declarative-ly wrap a method with boiler plate code. A filter doesn't know what you annotated so you can't do this logic there.

Finally some people think that an additional service layer is overrated for small web applications or REST only applications and that active record / DAOs plus controllers are enough (see Spring Roo ... it just recently added a service layer). In which case as mentioned earlier you often need the @Transaction support in your controller.

Otherwise there really isn't a good use case with modern Java (and/or AspectJ). IMHO I don't use dynamic proxies anymore.

Community
  • 1
  • 1
Adam Gent
  • 47,843
  • 23
  • 153
  • 203
  • All your examples can be done easily, and much less intrusively, by using filters. Spring has supported CGLib proxies since forever (at least Spring 2.0 if not earlier). My question is essentially - since controllers are simple, and filters exist to wrap their requests and responses already, why would you prefer a proxy to do anything for a controller rather than use a filter? – MetroidFan2002 Aug 21 '12 at 14:43
  • @MetroidFan2002 No they can't. Its annoying to say add some logic on a particularly RequestMapping as you have to leave the controller and edit some other file (add an interceptor). See my updated answer. – Adam Gent Aug 21 '12 at 15:40