对方进行预处理和后处理的两种方法

来源:互联网 发布:mac优酷怎么缓存 编辑:程序博客网 时间:2024/05/02 00:25
对方进行预处理和后处理的两种方法:动态代理和Spring AOP中的Advice,具体的是使用举例如下: 


1) 首先是公用部分的声明:定义了一个接口和对应的实现类,以及用来判断拦截方法的两个注解。 


首先定义一个接口 

public interface Hello { 

@MethodLog("执行 问候") 

void sayHello(String name); 


@MyMethodLog("执行 self") 
    void sayMySelf(String self); 



接口的实现 
public class HelloImpl implements Hello { 
@Override 
//@MethodLog("执行 问候") 
public void sayHello(String name) { 
    System.out.println("hello, " + name); 


@Override 
public void sayMySelf(String self) { 
    System.out.println("hello "+self); 


public static void main(String[] args) { 
    Hello hello = new HelloImpl(); 
    hello.sayHello("alice"); 




定义两个注解 
注解1的定义 
@Target({ METHOD }) 
@Retention(RUNTIME) 
public @interface MethodLog { 
    public String value() default ""; 


注解2的定义 
@Target({ METHOD }) 
@Retention(RUNTIME) 
public @interface MyMethodLog { 
    public String value() default ""; 


2)使用代理的方式拦截 
目的:通过动态代理的方式拦截要代理类的所有方法,然后判断拦截到的方法上是否标注了MethodLog的注解,
如果是,在执行方法的前后分别输出:方法名 Beging.和方法名 End. 

定义一个实现了InvocationHandler接口的类,实现invoke方法 
public class ProxyInvocationHandler implements InvocationHandler { 

private Object target; 

public ProxyInvocationHandler(Object target) { 
    this.target = target; 


@Override 
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 

//判断拦截到的方法是否有MethodLog的注解 
boolean methodLogAnnotated = method.isAnnotationPresent(MethodLog.class); 
    if (methodLogAnnotated) { 
        System.out.println(method.getName() + " Begin."); 
    } 

//通过反射的方式调用被代理的对象的方法 
Object ret = method.invoke(target, args); 

    if (methodLogAnnotated) { 
        System.out.println(method.getName() + " End."); 
    } 
    return ret; 



上述定义的代理类的使用的方式 
public class ProxyCall { 

public static void main(String[] args) { 

    final Hello hello = new HelloImpl(); 

    Hello helloProxy = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class<?>[] { Hello.class }, 
    new ProxyInvocationHandler(hello)); 

helloProxy.sayHello("alice"); 

}

3)使用Spring AOP中的Advice拦截 

目的:通过Advice的方式,在被拦截到的所有方法执行前后输出一些信息,如果被拦截的方法上标注了MethoLog注解,
在该方法执行的前后分别输出:执行 问候 Begin.和执行 问候 end.;如果被拦截的方法上标注了MyMethod注解,在该方法
执行的前后分别输出:执行 slef Begin.和执行 self End. 

首先定义实现了 MethodBeforeAdvice和 AfterReturningAdvice接口的类,分别实现他们各自的before方法和after方法 
public class MethodLogAdvice implements MethodBeforeAdvice, AfterReturningAdvice { 

@Override 
public void before(Method method, Object[] args, Object target) throws Throwable { 

//获取方法的所有注解 
Annotation[] annotations = method.getAnnotations(); 
for (Annotation annotation : annotations) { 

if (annotation.annotationType() == MethodLog.class) { 
//标注了MethodLog注解的处理 
MethodLog methodLog = method.getAnnotation(MethodLog.class); 
System.out.println(methodLog.value()+" Begin."); 
}else if(annotation.annotationType() == MyMethodLog.class){ 
//标注了MyMethodLog 注解的处理 
MyMethodLog myMethodLog = method.getAnnotation(MyMethodLog.class); 
System.out.println(myMethodLog.value() + " Begin"); 




@Override 
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { 


Annotation[] annotations = method.getAnnotations(); 
for (Annotation annotation : annotations) { 
if (annotation.annotationType() == MethodLog.class) { 
MethodLog methodLog = method.getAnnotation(MethodLog.class); 
System.out.println(methodLog.value()+" Begin."); 
}else if(annotation.annotationType() == MyMethodLog.class){ 
MyMethodLog myMethodLog = method.getAnnotation(MyMethodLog.class); 
System.out.println(myMethodLog.value() + " Begin"); 





使用的方式: 
public class SpringAOP { 

public static void main(String[] args) { 
//定义代理工厂 
ProxyFactory factory = new ProxyFactory(new HelloImpl()); 
//为代理工厂添加接口 
factory.addInterface(Hello.class); 
MethodLogAdvice advice = new MethodLogAdvice(); 
// 为代理工厂添加自己定义的Advice 
factory.addAdvice(advice); 

Hello hello = (Hello) factory.getProxy(); 
hello.sayHello("alice"); 
hello.sayMySelf("self"); 

0 0
原创粉丝点击