2015-07-21 20 views
2

我想获得方法的结果,然后将它们排入ActiveMQ。因此,我决定创建一个注释(比如@Enqueue(“My_Queue”)),它可以得到结果并将其发送给My_Queue。如何用注解获得方法结果?

@ResponseBody 
@Enqueue("My_Queue") 
@RequestMapping("/list") 
public MyClass list() { 
    return myService.getAll(); 
} 

这里是注释本身:

@Target(value = ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Enqueue { 

/** 
* The Name Of The Queue 
*/ 
String value() default "General_Message_Queue"; 

} 

所以,我应该怎么做才能创造这样的注释(A-Z,请)?

回答

2

你需要写下面的代码捕捉。

Class aClass = MyClass.class; 
Annotation[] annotations = aClass.getAnnotations(); 

for(Annotation annotation : annotations){ 
    if(annotation instanceof Enqueue){ 
     Enqueue myAnnotation = (Enqueue) annotation; 
     if(myAnnotation.name().equals("Enqueue")){ 
     //do your work 
     System.out.println("value: " + myAnnotation.value()); 
     } 
    } 
} 

更新:

注释不“触发” ......你必须编写代码,以查找他们的存在,并采取行动。

“代码”可以在运行时执行,但更常用的是在编译时使用Annotation Processing Tool来改变源代码以注入适合注解的额外代码,通常是交叉代码。

参考链接:https://stackoverflow.com/a/13040933/1326692

更新:通过查看您的意见,似乎你想要的东西通过动态您可以将您的注释方法调用之前做你的东西。为此,您需要创建如下所示的代理。

1:MyInterface.java

public interface MyInterface { 
    void test(); 
} 

2:Enqueue.java

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Enqueue { 

    public String value() default "General_Message_Queue"; 
} 

3. MyClass.java

import java.lang.reflect.Proxy; 

public class MyClass implements MyInterface { 

    @Enqueue 
    public void test() { 
    System.out.println("Inside test"); 
    } 

    public static void main(String[] args) throws IllegalArgumentException, InstantiationException, IllegalAccessException { 
    MyInterface test = (MyInterface) getProxyInstance(MyClass.class, MyInterface.class); 
    test.test(); 
    } 

    @SuppressWarnings("rawtypes") 
    public static Object getProxyInstance(Class clazz, Class interfaze) throws IllegalArgumentException, 
     InstantiationException, IllegalAccessException { 
    Object proxy = 
     Proxy.newProxyInstance(MethodInvocationHandler.class.getClassLoader(), 
      new Class[] {interfaze}, new MethodInvocationHandler(clazz.newInstance())); 
    return proxy; 
    } 
} 

4:MethodInvocationHandler.java

import java.lang.annotation.Annotation; 
import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method; 

public class MethodInvocationHandler implements InvocationHandler { 
    private Object proxied; 

    public MethodInvocationHandler(Object proxied) { 
    this.proxied = proxied; 
    } 

    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    Method m = proxied.getClass().getMethod(method.getName(), method.getParameterTypes()); 
    if (m.isAnnotationPresent(Enqueue.class)) { 

     // do your work here 
     System.out.println("Before " + m.getName() + " call..!"); 

     /** also you can get annotation and access it's properties..! */ 
     Enqueue annotation = m.getAnnotation(Enqueue.class); 
     System.out.println("name: " + annotation.value()); 

    } 

    /** also you can get all the annotations if you want */ 
    Annotation[] annotations = method.getDeclaredAnnotations(); 
    for (Annotation annotation : annotations) { 
     // do your annotation specific work here like this, 
     if (annotation instanceof Enqueue) { 
     // do your work here. 
     } 
    } 
    return method.invoke(proxied, args); 
    } 
} 

我希望它能帮助:)

+0

但是这个过程需要在每个方法返回后触发。 – Khodabakhsh

+1

此外,myAnnotation.value()为我们提供了“My_Queue”,它是ActiveMQ上返回值应该入队的队列的名称。 – Khodabakhsh

+0

请看我更新的答案。 –

3

方面一定是你在找什么。由于您使用的是Spring,请查看Spring AOP:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

随着咨询@AfterReturning和切入点@annotation(package.to.Enqueue),你就可以每@Enqueue注解的方法被调用时访问返回值:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-advice-after-returning

然后您就可以将它发送到队列中。

2

如果您使用spring-aop或任何第三方aop库,那么您可以应用下面的代码。

import java.util.ArrayList; 
import java.util.Collection; 

import org.apache.log4j.Logger; 
import org.aspectj.lang.annotation.AfterThrowing; 
import org.aspectj.lang.annotation.Aspect; 
import org.springframework.stereotype.Component; 

@Aspect 
@Component 
public class EnqueueServiceMonitor { 

    private static final Logger LOGGER = Logger 
      .getLogger(EnqueueServiceMonitor.class); 

    public EnqueueServiceMonitor() { 
    } 

    @AfterReturning(value = "@annotation(com.enqeue.annotation.Enqueue) && args(myClass,..)") 
    public void doProcess(MyClass myClass, 
      Exception ex) { 
     //do the code here. This method will call every time whenever your MyClass.list() method will be called. 
     //Or other method which have this annotation and return myClass object. 
    } 
} 


@ResponseBody 
@Enqueue("My_Queue") 
@RequestMapping("/list") 
public MyClass list() { 
    return myService.getAll(); 
} 

如果你的方法有不同的返回类型,那么你必须为特定的返回类型写更多的aop建议。