前面介绍了Guice的绑定和注入的方法,下面我们就来看看Guice的AOP,面向前面编程。
(1)创建Hello,HelloImpl类
package guice.aop;
import com.google.inject.ImplementedBy;
/**
* 定义一个Hello接口,在定义一个sayHi方法
* @author Java_Le
* @Date 2014-5-3下午12:54:43
* @ClassName Hello.java
*/
@ImplementedBy(HelloImpl.class)
public interface Hello {
void sayHi() ;
void doSomething() ;
}
package guice.aop;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
/**
*
* @author Java_Le
* @Date 2014-5-3下午12:55:41
* @ClassName HelloImpl.java
*
* Hello接口的实现类
*/
@Singleton
public class HelloImpl implements Hello{
/**
* Guice中给某个方法添加拦截器是通过@Named注解来完成的,一个拦截器会绑定一个带xxx的@Named注解,
* 当你这个对象时通过guice容器创建的,当你访问带xxx的@Named注解的时候,就会被拦截器拦截到
*/
@Override
@Named("interceptor")
public void sayHi() {
System.out.println("HelloImpl exec sayHi method");
}
@Override
@Named("log")
public void doSomething() {
System.out.println("HelloImpl exec doSomething method");
}
}
(2)创建一个拦截器
package guice.aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
doBefore() ;
//真正要去执行的方法
//可以再这个地方做一些验证,比如是否能够去执行这个方法等
Object ret = invocation.proceed() ;
doAfter() ;
return ret;
}
//在执行真正的逻辑之前执行
public void doBefore(){
System.out.println("我是在方法之前要做的事情");
}
//支执行真正的逻辑之后执行
public void doAfter(){
System.out.println("我是在方法执行之后做的事情");
}
}
(3)创建一个测试程序
package guice.aop;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.matcher.Matchers;
import com.google.inject.name.Names;
public class Client {
//注入hello属性
@Inject
private Hello hello ;
public static void main(String[] args) {
Injector in = Guice.createInjector(new Module(){
@Override
public void configure(Binder binder) {
//将MyInterceptor绑定到所有方法上带interceptor和log @Named注解的方法上,我们可以看到Guice的拦截器是可以匹配任意多个@Named注解的。
//Matchers 控制拦截器要拦截的范围,可以确定到某个package中,可以指定为某个class,可以指定为某个类的子类等等
//下面我们用的是任何类Matchers.any()
binder.bindInterceptor(Matchers.any(), Matchers.annotatedWith(Names.named("interceptor")), new MyInterceptor()) ;
binder.bindInterceptor(Matchers.any(), Matchers.annotatedWith(Names.named("log")), new MyInterceptor()) ;
}
}) ;
//通过Guice来得到一个Hello实例,其实是指向的HelloImpl实例
Hello hello = in.getInstance(Hello.class) ;
hello.sayHi() ;
hello.doSomething() ;
}
}
输出结果:
我是在方法之前要做的事情
HelloImpl exec sayHi method
我是在方法执行之后做的事情
我是在方法之前要做的事情
HelloImpl exec doSomething method
我是在方法执行之后做的事情