ERLEDIGT
NEIN
NEIN
ANTWORTEN
12
12
ZUGRIFFE
931
931
EMPFEHLEN
-
Ich hab mich gestern mal bisschen mit AspectJ beschäftigt und irgendwie schein ich noch nicht so ganz dahinter zu kommen.
Mal ein einfaches Beispiel. Nehmen wir an, ich hab folgenden Controller
Code :1 2 3 4 5 6 7 8 9 10
@Controller public class TestControllerImpl { @RequestMapping(value="/test.do") @TestAnnotation public String test(TestForm form, HttpServletRequest request) { return "test"; } }
und den Abschnitt in meinem Aspect
Code :1 2 3 4 5 6 7
@Before(value = "testAnnotation() && args(form, request)") public void beforeValidation(Object form, HttpServletRequest request) { doSomething(form, request); } @Pointcut("@annotation(annotation.TestAnnotation)") public void testAnnotation() {}
dann klappt das soweit.
Jetzt implementier ich mal das Interface im TestControllerImpl
Code :1 2 3 4
public interface TestController { public String test(TestForm form, HttpServletRequest request); }
Bei der Einstellung Standard-Einstellung proxy-target-class="false" kommt
und das mapping auf "test.do" klappt nichtmehr. Bei der proxy-target-class="true" ändert sich der output inCode :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
DEBUG - Creating shared instance of singleton bean 'testControllerImpl' DEBUG - Creating instance of bean 'testControllerImpl' DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#0' DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#1' DEBUG - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' DEBUG - Eagerly caching bean 'testControllerImpl' to allow for resolving potential circular references DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#0' DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#1' DEBUG - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#0' DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#1' DEBUG - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' DEBUG - Creating implicit proxy for bean 'testControllerImpl' with 0 common interceptors and 2 specific interceptors DEBUG - Creating JDK dynamic proxy: target source is SingletonTargetSource for target object [de.pixelcasino.frontend.controller.TestControllerImpl@1890909] DEBUG - Finished creating instance of bean 'testControllerImpl'
und das ganze scheint zu klappen. Was mache ich falsch, dass das bei der Standardeinstellung nicht klappt.Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
DEBUG - Creating shared instance of singleton bean 'testControllerImpl' DEBUG - Creating instance of bean 'testControllerImpl' DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#0' DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#1' DEBUG - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' DEBUG - Eagerly caching bean 'testControllerImpl' to allow for resolving potential circular references DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#0' DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#1' DEBUG - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#0' DEBUG - Returning cached instance of singleton bean 'org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#1' DEBUG - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' DEBUG - Creating implicit proxy for bean 'testControllerImpl' with 0 common interceptors and 2 specific interceptors DEBUG - Creating CGLIB2 proxy: target source is SingletonTargetSource for target object [de.pixelcasino.frontend.controller.TestControllerImpl@1d1f4fe] DEBUG - Unable to apply any optimisations to advised method: public java.lang.String de.pixelcasino.frontend.controller.TestControllerImpl.test(javax.servlet.http.HttpSession,javax.servlet.http.HttpServletRequest) DEBUG - Found finalize() method - using NO_OVERRIDE DEBUG - Found 'hashCode' method: public native int java.lang.Object.hashCode() DEBUG - Unable to apply any optimisations to advised method: protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException DEBUG - Found 'equals' method: public boolean java.lang.Object.equals(java.lang.Object) DEBUG - Unable to apply any optimisations to advised method: public java.lang.String java.lang.Object.toString() DEBUG - Method is declared on Advised interface: public abstract int org.springframework.aop.framework.Advised.indexOf(org.aopalliance.aop.Advice) DEBUG - Method is declared on Advised interface: public abstract int org.springframework.aop.framework.Advised.indexOf(org.springframework.aop.Advisor) DEBUG - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isFrozen() DEBUG - Method is declared on Advised interface: public abstract org.springframework.aop.TargetSource org.springframework.aop.framework.Advised.getTargetSource() DEBUG - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvisor(org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException DEBUG - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvisor(int,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException DEBUG - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setTargetSource(org.springframework.aop.TargetSource) DEBUG - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setPreFiltered(boolean) DEBUG - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isProxyTargetClass() DEBUG - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setExposeProxy(boolean) DEBUG - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isExposeProxy() DEBUG - Method is declared on Advised interface: public abstract org.springframework.aop.Advisor[] org.springframework.aop.framework.Advised.getAdvisors() DEBUG - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvice(int,org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException DEBUG - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvice(org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException DEBUG - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isPreFiltered() DEBUG - Method is declared on Advised interface: public abstract java.lang.Class[] org.springframework.aop.framework.Advised.getProxiedInterfaces() DEBUG - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isInterfaceProxied(java.lang.Class) DEBUG - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.removeAdvisor(org.springframework.aop.Advisor) DEBUG - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.removeAdvisor(int) throws org.springframework.aop.framework.AopConfigException DEBUG - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.replaceAdvisor(org.springframework.aop.Advisor,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException DEBUG - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.removeAdvice(org.aopalliance.aop.Advice) DEBUG - Method is declared on Advised interface: public abstract java.lang.String org.springframework.aop.framework.Advised.toProxyConfigString() DEBUG - Method is declared on Advised interface: public abstract java.lang.Class org.springframework.aop.TargetClassAware.getTargetClass() DEBUG - Finished creating instance of bean 'testControllerImpl'
Geändert von ck2003 (07.06.09 um 16:52 Uhr)
-
07.06.09 17:06 #2
SpringAOP funktioniert im Defaultfall nur gegen Interfaces (Details in 6.1.3 hier. D.h. deine TestAnnotation müsste an das Interface um deinen Pointcut zu matchen. Durch proxy-target-class="true" kommt CGLib ins Spiel und es werden zur Laufzeit Subklassen deiner Beans erzeugt anstelle von wrappenden JDK Proxies. Dadurch gelangt die Annotation wieder in den Scope und der Pointcut matcht.
Gruß
OllieIn theory, there is no difference between theory and practice. In practice, there is!
www.olivergierke.de
-
Ok, dass die Annotation dann auch rüber muss war mir nicht klar, aber das wäre ja schnell gemacht.
Davon abgesehen kommt er aber sowieso nie zu dem Punkt, weil das mapping auf "/test.do" gar nichtmehr erkannt wird.
Code :1
DEBUG - Rejected bean name 'testControllerImpl': no URL paths identified
-
07.06.09 17:47 #4
Was heißt "nicht mehr"? In welcher Konstellation denn?
In theory, there is no difference between theory and practice. In practice, there is!
www.olivergierke.de
-
Erst hatte ich es so.
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@Controller public class TestControllerImpl implements TestController { @RequestMapping(value="/test.do") public String test(TestForm form, HttpServletRequest request) { return "test"; } } public interface TestController { @TestAnnotation public String test(TestForm form, HttpServletRequest request); }
Dann findet er im DefaultAnnotationHandlerMapping aber das @Controller nichtmehr als Annotation, weswegen er gar nicht erst versucht die URLs zu extrahieren. Wenn ich mal testweise das @Controller zusätzlich ans Interface setze, was wohl nicht im Sinne Erfinders ist, findet er das zwar dann, aber spätestens beim Extrahieren von @RequestMapping gibt er auf.
-
07.06.09 18:14 #6
Sicher? Hast du die Logausgaben für die Konfiguration mal da? Hab grad mal im Code geschaut und seh keinen Grund warum das nicht tun sollte...
In theory, there is no difference between theory and practice. In practice, there is!
www.olivergierke.de
-
Was sollte gehen? Wenn @Controller und @RequestMapping in TestControllerImpl liegen? Hab ich da was falsch konfiguriert? An den Annotation in TestControllerImpl selbst kommt er bei mir nie vorbei.
Außer
loggt der bei mir in dem Bereich zu dem Fall nix oder könnte davor oder dahinter noch was spannendes für dich auftauchen.Code :1
DEBUG - Rejected bean name 'testControllerImpl': no URL paths identified
-
07.06.09 19:17 #8
Ich meine, dass es so funktionieren sollte, wie du es da hast... Die kritische Methode ist wohl DefaultAnnotationHandlerMapping.determineUrlsForHandler(String beanName). Da wirft er deine Bean weg, obwohl er das nicht sollte. Da solltest du mal den Debugger drauf ansetzen und schauen, was da drin genau passiert.
In theory, there is no difference between theory and practice. In practice, there is!
www.olivergierke.de
-
Mal am Beispiel von
was im unteren Bereich der angesprochenen Methode zu finden ist.Code :1
AnnotationUtils.findAnnotation(handlerType, Controller.class)
Zuerst schaut er im Proxy selbst: der hat die Annotation nicht.
Dann geht er die Interfaces durch.:
TestController
org.springframework.aop.SpringProxy
org.springframework.aop.framework.Advised
als nächstes geht er auf die Superklasse
java.lang.reflect.Proxy
die hat nur
Serializable
und dann kommt noch java.lang.Object dran
wer von denen sollte denn nun die Annotationen von TestControllerImpl vorhalten?
-
07.06.09 21:53 #10
Args, daran hab ich nicht gedacht... wenn die Klasse geproxied wird, dann hat sie natürlich nicht mehr den Typ der Implemenierung. Damit sind auch die Annotationen nicht mehr sichtbar. Hast du mal geschaut, ob es a) nen Bug dazu im JIRA gibt? und/oder b) es im 3.0 Milestone evtl. schon gefixt ist?
EDIT: Hab grad kurz mit Eberhard Wolff gesprochen. Scheint tatsächlich ein Bug zu sein. Ich konnte auf die Schnelle im JIRA nix finden. Ich file da morgen früh mal was...In theory, there is no difference between theory and practice. In practice, there is!
www.olivergierke.de
-
Danke erstmal; dann weiß ich ja schonmal wo ich dran bin.
edit: Ich würd sagen der triffts ganz gut.
http://jira.springframework.org/browse/SPR-5084
-
08.06.09 08:48 #12
Du kannst in der Zwischenzeit ja einfach die Annotationen an das Interface nageln. Das hast du vermutlich ja eh nur eingeführt um AOP ohne CGLib nutzen zu können.
Gruß
OllieIn theory, there is no difference between theory and practice. In practice, there is!
www.olivergierke.de
-
Genau aus dem Grund; darum ist es auch nicht lebensnotwendig.
Aber die ans Interface zu setzen klappt leider nicht, weil @RequestMapping auf Methoden-Ebene nur bei Superklassen, nicht bei Interfaces überprüft wird. Darum lass ichs erstmal so und behalte das Ganze im Auge.
Ähnliche Themen
-
[Spring] ResourceMessages in Controller oder Beans?
Von Hardi82 im Forum Enterprise Java (JEE, J2EE, Spring & Co.)Antworten: 4Letzter Beitrag: 27.10.08, 08:49 -
Spring: Bean-Initialisierung in einem Webprojekt -> NullPointerException
Von Wilde im Forum Enterprise Java (JEE, J2EE, Spring & Co.)Antworten: 1Letzter Beitrag: 01.10.08, 08:30 -
Komisches Verhalten von einem.net Programm
Von Bellm im Forum .NET CaféAntworten: 9Letzter Beitrag: 18.09.08, 16:09 -
Spring / DispatcherServlet: MVC - Controller
Von gtm im Forum Enterprise Java (JEE, J2EE, Spring & Co.)Antworten: 0Letzter Beitrag: 18.08.08, 18:05 -
Asbro: Alternative zu AspectJs AJDT Visualizer zur Visualisierung von Aspekten
Von Thomas Darimont im Forum JavaAntworten: 0Letzter Beitrag: 28.04.08, 11:29





Zitieren
Login





