These classes work fine as they are listed above (although I have omitted some attributed for brevity.)
However, the above class no longer maps the subscription topic if the add method is annotated with @PreAuthorize. This happens because the presence of @PreAuthorize breaks org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler#afterPropertiesSet(). This method calls applicationContext.getType(beanName) which returns Proxy with the annotation, but Controller without. When Proxy is returned AbstractMethodMessageHandler thinks the class is not a handler and does not try to detect handler methods.
For now, we have had to revert to doing the auth checks manually.
You can clone the repository and then cd into or import the #17951 sub-directory into an IDE. The project isn't fully set up to serve requests but there is enough configuration to start up and initialize the mappings + security proxying. You can see in the logs on startup the mappings and you can check that it's proxied with the debugger.
I meant that can Spring messaging/websocket handle both cases (JDK dynamic proxy or CGlib)? We could configure it to use class based proxy but it feels like that the library should be able to cope with both cases?
Ah I see what you mean now. The support for @MessageMapping methods is equivalent to what we have for @RequestMapping. In my comments above I indicted I created a sample project and demonstrated it works.
As for adding ApplicationListener, if that's the only interface your controller implements and you have not chosen class-based proxying, then it can't work. If you want JDK based proxying you need to create an interface with @RequestMapping annotations.