为GWT增加AOP支持,GWTENT 0.5发布
程序员文章站
2022-03-24 11:02:48
...
GWTENT 0.5 发布,在新的版本中不仅仅增强对反射的支持,重要的是为GWT客户端代码提供一个AOP实现。
项目主页:http://code.google.com/p/gwt-ent/
下载页:http://code.google.com/p/gwt-ent/downloads/list
AOP WIKI 页:http://code.google.com/p/gwt-ent/wiki/AOP
连接点同时支持AspectJ注解风格与Google Guice Matcher类,所有连接点匹配与Matcher类都只运行在HostModel与编译期,这也意味着你可以使用所有JAVA类而不受GWT客户端代码限制,同时这些代码不会在最终的目标JavaScript代码里出现。
通知(Advice)支持以下五种:
使用方法
使用方法非常简单
切面类
使用@Aspect声明
需要被增强的类
输出结果
项目主页:http://code.google.com/p/gwt-ent/
下载页:http://code.google.com/p/gwt-ent/downloads/list
AOP WIKI 页:http://code.google.com/p/gwt-ent/wiki/AOP
连接点同时支持AspectJ注解风格与Google Guice Matcher类,所有连接点匹配与Matcher类都只运行在HostModel与编译期,这也意味着你可以使用所有JAVA类而不受GWT客户端代码限制,同时这些代码不会在最终的目标JavaScript代码里出现。
通知(Advice)支持以下五种:
- 前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
- 后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
- 异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
- 最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
- 环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
使用方法
使用方法非常简单
public void testAOP(){ Phone phone = (Phone) GWT.create(Phone.class); Receiver auntJane = phone.call(123456789); System.out.println(auntJane); }
切面类
使用@Aspect声明
@Aspect public static class PhoneLoggerInterceptor { //execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) @Before("execution(* com.gwtent.client.test.aop.Phone.call(java.lang.Number))") public void beforeCall(MethodInvocation invocation) { for (Object arg : invocation.getArguments()){ System.out.println("Do something in PhoneLoggerInterceptor, Before..."); if (arg instanceof Number) System.out.println("Call to: " + arg); } } @AfterReturning(pointcut = "execution(* com.gwtent.client.test.aop.Phone.call(java.lang.Number))", returning = "returnValue") public void afterReturningCall(MethodInvocation invocation, Object returnValue) { System.out.println("Do something in PhoneLoggerInterceptor, AfterReturning..."); if ((returnValue != null)){ if (returnValue instanceof Number) System.out.println("Returning Number: " + returnValue.toString()); else System.out.println("Returning Object: " + returnValue.toString()); }else{ System.out.println("Returning Object is NULL?"); } } @After("execution(* com.gwtent.sample.client.Phone.call(java.lang.Number))") public void afterCall(MethodInvocation invocation) { for (Object arg : invocation.getArguments()){ System.out.println("Do something in PhoneLoggerInterceptor, After..."); if (arg instanceof Number) System.out.println("After Call: " + arg); } } } @Aspect public static class PhoneRedirectInterceptor { @Around("execution(* com.gwtent.client.test.aop.Phone.call(java.lang.Number))") public Object invoke(MethodInvocation invocation) throws Throwable { invocation.proceed(); System.out.println("Do something in PhoneRedirectInterceptor..."); return new Receiver("Alberto's Pizza Place"); } }
需要被增强的类
public class Phone implements Aspectable { private static final Map<Number, Receiver> RECEIVERS = new HashMap<Number, Receiver>(); static { RECEIVERS.put(123456789, new Receiver("Aunt Jane")); RECEIVERS.put(111111111, new Receiver("Santa")); } /** * the phone number, like your home number */ private Number number; public Receiver call(Number number) { System.out.println("The call here..."); Receiver result = RECEIVERS.get(number); if (result != null) return result; else throw new NumberNotFoundException("Can't found receiver, number: " + number); } public Receiver call(String number){ System.out.println("The call here..."); return RECEIVERS.get(111111111); } public String toString(){ return super.toString(); } public void setNumber(Number number) { this.number = number; } public Number getNumber() { return number; } public static class NumberNotFoundException extends RuntimeException{ /** * */ private static final long serialVersionUID = 1L; public NumberNotFoundException(String msg){ super(msg); } } public static class Receiver { private final String name; public Receiver(String name) { this.name = name; } @Override public String toString() { return getClass().getName() + "[name=" + name + "]"; } }
输出结果
Do something in PhoneLoggerInterceptor, Before... Call to: 123456789 Validate, you cann't dail to 0, current Number(most time it's null): null The call here... Do something in PhoneRedirectInterceptor... Do something in PhoneLoggerInterceptor, After... After Call: 123456789 Do something in PhoneLoggerInterceptor, AfterReturning... Returning Object: com.gwtent.sample.client.Phone$Receiver[name=Alberto's Pizza Place] com.gwtent.sample.client.Phone$Receiver[name=Alberto's Pizza Place]