spring+springmvc+mybatis(SSM)SSM(Spring+SpringMVC+MyBatis)SSM

拦截器

2019-04-14  本文已影响5人  xm的那年

由于动态代理一般都比较难理解,程序设计者都会设计一个拦截器接口供开发者使用,开发者只要知道拦截器接口的方法,含义和作用即可。无须知道动态代理是怎么实现的,用JDK动态代理来实现一个拦截器的逻辑,为此先定义拦截器接口Interceptor,

package com.lean.ssm.chapter2.Inceptor;

import java.lang.reflect.Method;


public interface Interceptor {
    
public boolean before(Object proxy,Object target,Method method,Object[] args);

public void around(Object proxy,Object target,Method method,Object[] args);

public void after(Object proxy,Object target,Method method,Object[] args);
}

/**

*/
实现Interceptor的实现类,MyInterceptor

package com.lean.ssm.chapter2.Inceptor;

import java.lang.reflect.Method;

public class MyInterceptor implements Interceptor{

    @Override
    public boolean before(Object proxy, Object target, Method method,
            Object[] args) {
        // TODO Auto-generated method stub
        System.out.println("反射方法前调用");
        
        return  true;
//      不反射被代理对象原有方法
    }

    @Override
    public void around(Object proxy, Object target, Method method, Object[] args) {
        // TODO Auto-generated method stub
        System.out.println("取代反射方法");
    }

    @Override
    public void after(Object proxy, Object target, Method method, Object[] args) {
        // TODO Auto-generated method stub
        System.out.println("反射方法后的逻辑");
    }

}

它实现了所有的Interceptor的方法,使用JDK动态代理,就可以实现这些方法在适当的调用逻辑

package com.lean.ssm.chapter2.Inceptor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.lean.ssm.chapter.proxy.HelloWorld;
import com.lean.ssm.chapter.proxy.HelloWorldImpl;

public class InterceptorProxy implements InvocationHandler {
// 使用JDK动态代理就可以去实现这些方法在适当的时候调用逻辑。
    private Object target;
//  真实对象
    private String interceptorClass=null;
//  拦截器权限定名
    public InterceptorProxy(Object target,String interceptorClass){
        this.interceptorClass=interceptorClass;
        this.target=target;
    }
    public static Object bind(Object target,String interceptorClass){
//      取得代理对象  interceptorClass的拦截器的类名
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorProxy(target,interceptorClass));
        
    }
    /**
     * 通过代理对象调用方法,首先进入这个方法
     * proxy 代理对象
     * method  方法,被调用方法
     * args 方法的参数
     * 
     */
    
    
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        if(interceptorClass==null){
//          如果没有设置拦截器则直接反射原有方法
            return method.invoke(target,args);
        }
        Object result=null;
//      通过反射生成拦截器
        Interceptor interceptor=(Interceptor) Class.forName(interceptorClass).newInstance();
//      实例化拦截器
//      调用前置方法
        if(interceptor.before(proxy, args, method, args)){
//          反射原有的方法
            result=method.invoke(target, args);
        }else{
//          返回false则执行around方法
            interceptor.around(proxy, args, method, args);
        }
//      调用后置方法
        interceptor.after(proxy, args, method, args);
        return result;
    }
    public static void main(String[] args) {
        HelloWorld proxy=(HelloWorld)InterceptorProxy.bind(new HelloWorldImpl(), "com.lean.ssm.chapter2.Inceptor.MyInterceptor");
        proxy.sayHelloWorld("AJMAN");
    }

}

这里有两个属性,一个是target,它是真实对象,另一个是字符串,interceptorClass,它是一个拦截器的全限定名 ,
解释一下代码的执行步骤

上一篇 下一篇

猜你喜欢

热点阅读