guice2之AOP

Guice之前也是花了很少时间看一下,现在几乎忘了。再一看以前写的几篇关于guice的博客,写得一点都不到位,甚至有许多地方都没讲清楚,真是惭愧!现在突然又想关注一下IOC方面的东西,因此想好好看看,Guice到底能做些什么,能做到什么程度。有空也想看看其源码。看了一下源码才发现,其实源码只包含guice部分,而实际上guice实现了其它一些第三方的源码,至少包括三个组件的源码:
一、aopalliance.jar,此包就是aop联盟定义的一组关于AOP的公共接口。
二、cglib,反射使用目前公认的最好的cglib组件。
三、asm,由于cglib使用了asm组件,所以asm也很重要。

错误的估计了形式,也更加验证了guice的确是强大的,因此这些都是目前非常优秀的组件。关于AOP,了解不多,以前有想过学习aspectj的,但的确有点复杂,不太适合自己这种喜欢轻量级组件的要求,所以没有迈出那一步,关注guice时才发现,居然有AOP的功能,于是就花了点时间试一下,虽然功能并不是很完善,但使用起来也很简单,对于大多数要求并不复杂的应用来说,已经不错了。

由于guice2使用注解,所以看起来更简单,下面以验证用户为例,首先建一个注解:

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

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



然后再建立一个拦截器:

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class ValidUserInterceptor implements MethodInterceptor {
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		Object[] args = invocation.getArguments();
		for (int i = 0; i < args.length; i++) {
			System.out.println(args[i]);
		}
		return invocation.proceed();
	}
}


注意上面的MethodInterceptor来自aopalliance包而不是cglib包。上面方法的作用是打印拦截方法的参数值。

要把拦截器与注解关联起来,而关联的动作是在Module中进行了的:

public class ValidUserModule extends AbstractModule {

	@Override
	protected void configure() {
		
		bind(UserService.class).to(UserServiceImp.class);  
		bindInterceptor(Matchers.any(), Matchers.annotatedWith(ValidUser.class), 
		        new ValidUserInterceptor());
	}
}


上面绑定拦截器使用了bindInterceptor方法,需要注意的是匹配规则,上面使用了较简单的Matchers.any(),如果有一些其它的要求,可以选择使用not,only等方法,它们使得拦截器使用起来更加的灵活。

实例还用到两个辅助的类:

public interface UserService {

	public void editUser(String username,String password);
}


public class UserServiceImp implements UserService{

	@ValidUser
	public void editUser(String username,String password){
		System.out.println("UserService editUser");
	}
}


测试类:

public class ValidUserTest {

	@Test
	public void validUser(){
		Injector injector = Guice.createInjector(new ValidUserModule());
		UserService us = injector.getInstance(UserService.class);
		us.editUser("fans","java");
	}
}


按照拦截器的要求,结果会打印相应的参数值。输出为:
引用

fans
java
UserService editUser


一个简单的拦截过程就这样实现了。不过要使用guice拦截器,有几个限制因素:

引用

    * Classes must be public or package-private.
    * Classes must be non-final
    * Methods must be public, package-private or protected
    * Methods must be non-final
    * Instances must be created by Guice by an @Inject-annotated or no-argument constructor

你可能感兴趣的:(java,AOP,IOC)