2014-11-14 11 views
5

bir istek haritalama ile kontrolörün çeşit göz önüne alındığındaBir Spring denetleyicisinden AOP tavsiyesinde RequestMapping isteğini nasıl alırsınız?

@RequestMapping(value="/some/path", method=RequestMethod.POST) 
Eğer boy sınıfındaki yöntem değeri (RequestMethod.POST) almak istiyorum nasıl

?

POST isteğinde bulunan tüm denetleyici yöntemlerini takip etmek istiyorum.

Teşekkürler

+0

'@ Controller' bean'ını alın, çağrılan yöntemi alın, notu alın,' method' özniteliğini alın. –

cevap

4

Çözüm bulundu.

import org.aspectj.lang.reflect.MethodSignature; 
import java.lang.reflect.Method; 

@Pointcut("within(@org.springframework.stereotype.Controller *)") 
public void controller() {} 

// In advice 
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); 
Method method = methodSignature .getMethod(); 
RequestMethod[] requestMethods = method.getAnnotation(RequestMapping.class).method(); 

İçe aktardığınız sınıfa dikkat edin.

+0

Hala bunun yapılmasının bir yolu olmadığını düşünüyorum. Kendi cevabım canonical AspectJ kullanır ve yansıma gerektirmez. – kriegaex

6

@ AL13N: Kendi yanıtınız doğrudur, ancak ek açıklamaları bir parametreye bağlarsanız yansıma kullanmanız gerekmez. İşte POJO + AspectJ'de bir örnek. Spring AOP olarak bu da, aynı olmalıdır: Ana yöntemle

Örnek kontrol:

package de.scrum_master.app; 

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 

@Controller 
public class MyController { 
    @RequestMapping(value="/some/path", method=RequestMethod.POST) 
    public void foo() { 
     System.out.println("foo"); 
    } 
    public void bar() { 
     System.out.println("bar"); 
    } 

    public static void main(String[] args) { 
     MyController controller = new MyController(); 
     controller.foo(); 
     controller.bar(); 
    } 
} 

Unsur:

btw
package de.scrum_master.aspect; 

import org.aspectj.lang.JoinPoint; 
import org.aspectj.lang.annotation.Before; 
import org.aspectj.lang.annotation.Pointcut; 
import org.springframework.web.bind.annotation.RequestMapping; 

public aspect RequestMappingInterceptor { 
    @Pointcut(
     "within(@org.springframework.stereotype.Controller *) && " + 
     "@annotation(requestMapping) && " + 
     "execution(* *(..))" 
    ) 
    public void controller(RequestMapping requestMapping) {} 

    @Before("controller(requestMapping)") 
    public void advice(JoinPoint thisJoinPoint, RequestMapping requestMapping) { 
     System.out.println(thisJoinPoint); 
     System.out.println(" " + requestMapping); 
     System.out.println(" " + requestMapping.method()[0]); 
    } 
} 

, pointcut arasında && execution(* *(..)) parçasıdır Muhtemelen Spring AOP'da gerekli değildir, çünkü zaten yürütme noktalarını bilmektedir. AspectJ'de, AspectJ daha güçlü olduğu için call() ve diğer türdeki pointcut'ları hariç tutmanız gerekir. Yine de incitmez ve daha güvenli ve daha açıktır.

Konsol çıkışı:

execution(void de.scrum_master.app.MyController.foo()) 
    @org.springframework.web.bind.annotation.RequestMapping(headers=[], name=, value=[/some/path], produces=[], method=[POST], params=[], consumes=[]) 
    POST 
foo 
bar 

Düzenleme: Bahar AOP AspectJ'yi değil iken bu düzenin ısrar görünüyor çünkü Değiştirmeli parametreleri, joinpoint ilk danışma yöntemi parametre kılacak şekilde.

+0

Çözümünüzü denedim ve çalışmıyor gibi görünüyor. Point :: 0 'da resmi olmayan bağlantı noktasında hata alıyorum. –

+0

Benim için çalışıyor. Kopyala ve yapıştır eyleminde bir hata yaptın mı? – kriegaex

+1

Birisi, bir süre önce Spring AOP için “JoinPoint” parametresini en sonunda tavsiye imzasının başlangıcına koyması gerektiğini söyledi. Bunun doğru olduğunu sanmıyorum ama deneyebilirsiniz. Ben hiçbir şekilde bir Spring uzmanı değilim. – kriegaex