JDK动态代理使用拦截器

       一、简要介绍

       在java中有多种动态代理技术,比如JDK、CGLIB、ASM、javassist,其中最常用的动态代理技术有两种:一种是JDK动态代理,这是JDK自带的功能;另一种是CGLIB,这是第三方提供的一个技术。JDK动态代理&CGLIB(Code Generator Library,是一个强大的、高性能的代码生成库)动态代理。
     JDK动态代理是java.lang.reflect.*包提供的方式,它必须借助一个接口才能产生代理对象。由于动态代理一般比较难理解,程序设计者会设计一个拦截器接口供开发者使用,开发者只需要知道拦截器接口的方法、含义和作用即可,无须知道动态代理是怎么实现的。

        二、实现过程

1、目标接口及实现类:HelloWorld、HelloWorldImp,拦截器会对改业务进行拦截

public interface HelloWorld {
    public abstract void sayHelloWorld();

}

public class HelloWorldImp implements HelloWorld{
    @Override
    public void sayHelloWorld() {
        System.out.println("hello");
    }    

}

2、定义拦截器接口:Interceptor

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);
}

1)三个方法参数:proxy代理对象、target真实对象、method方法、args运行方法参数
2)before方法返回Boolean值,它在真实对象前调用。当为true时反射真实对象的方法;当返回false时,则调用around方法。
3)在before方法返回为false的情况下,调用around方法。
4)在反射真实对象方法或者around方法执行之后,调用after方法。

3、Interceptor接口实现类:MyInterceptor

public class MyInterceptor implements Interceptor{
    
    @Override
    public boolean before(Object proxy,Object target,Method method,Object[]args) {
        System.out.println("反射方法前逻辑");
        return false;//不反射被代理对象原有方法
    }
    @Override
    public void after(Object proxy,Object target,Method method,Object[]args) {
        System.out.println("反射方法后逻辑");
    }
    @Override
    public void around(Object proxy,Object target,Method method,Object[]args) {
        System.out.println("取代了被代理对象的方法");
    } 
}

4、在JDK动态代理中使用拦截器:InterceptorJdkProxy

public class InterceptorJdkProxy implements InvocationHandler{
    
    private Object target;//真实对象
    private String interceptorClass=null;//拦截器全限定名
    
    public InterceptorJdkProxy(Object target,String interceptorClass) {
        this.target=target;
        this.interceptorClass=interceptorClass;
    }
    
    /**
     * 绑定委托对象并返回一个【代理占位】
     * @param target真实对象
     * @return 代理对象【占位】
     * 
     */
    public static Object bind(Object target,String interceptorClass) {
        //取得代理对象,代理对象和真实对象产生关联
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorJdkProxy(target, interceptorClass));
    }
    
    @Override
    /*
     * 通过代理对象调用方法,首先进入这个方法
     * @param proxy 代理对象
     * @param method 方法,被调用方法
     * @param args 方法的参数
     * 
     */
    public Object invoke(Object proxy,Method method,Object[]args) throws Throwable {
        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;
    }

}

5、测试:MyInterceptorTest

public class MyInterceptorTest {
    public static void main(String[] args) {
        HelloWorld proxy=(HelloWorld)InterceptorJdkProxy.bind(new HelloWorldImp(), "test.MyInterceptor");
        proxy.sayHelloWorld();
    }

}

查看测试结果:

6、拦截器工作流程:

 

拦截器类 需要两个配合使用这里只有一个 @Configuration public class ServletContextConfig extends WebMvcConfigurerAdapter { public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("/templates/**").addResourceLocations("classpath:/templates/"); super.addResourceHandlers(registry); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HandlerMyInterceptorAdapter()).addPathPatterns("/**") .excludePathPatterns("/") // .excludePathPatterns("/expressions/getExpressionsList") .excludePathPatterns("/loginInfo/getCordByIsPhone") .excludePathPatterns("/loginInfo/login11") //token失效跳轉 .excludePathPatterns("/loginInfo/insertLoginInfo") //注册 .excludePathPatterns("/loginInfo/login") //登录 .excludePathPatterns("/upload") //上传文件 .excludePathPatterns("/uploadListen") //上传文件 .excludePathPatterns("/admin/user/goLogin") //后台跳转登录 .excludePathPatterns("/admin/user/login") //后台登录 .excludePathPatterns("/loginInfo/getLoginInfo") //忘记密码 .excludePathPatterns("/loginInfo/getCord") //短信验证码 .excludePathPatterns("/loginInfo/getIsLoginInfo") //判断验证码&&登录 .excludePathPatterns("/loginInfo/getIsLoginInfo1") //判断验证码 .excludePathPatterns("/loginInfo/setPassWord") //设置密码 ; } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } } @Component public class HandlerMyInterceptorAdapter implements HandlerInterceptor { @Autowired private HeartbeatServiceImpl heartbeatService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { String url = request.getRequestURI(); if (url.contains("admin")) { User user = (User) request.getSession().getAttribute("user"); try { if (user.equals(null)) { response.sendRedirect(serverConfig.SERVER + "admin/user/goLogin"); return false; } else { return true; } }catch (Exception e){ response.sendRedirect(serverConfig.SERVER + "admin/user/goLogin"); return false; } }else { String token = request.getHeader("token"); if (token != null) { Jedis jedis = new Jedis(com.sevenSteps.util.RedisConfig.HOST, RedisConfig.PORT); String s = jedis.get(token); if(token.equals(s)) { heartbeatService = SpringUtil.getBean(HeartbeatServiceImpl.class); return heartbeatService.setOutDate(token); }else { response.sendRedirect(serverConfig.SERVER + "loginInfo/login11"); return true; } }else { response.sendRedirect(serverConfig.SERVER + "loginInfo/login11"); return true; } } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值