动态代理设计模式&&类加载器

来源:互联网 发布:微信加友软件免费版 编辑:程序博客网 时间:2024/05/22 12:47
1动态代理对象介绍
Proxy提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
   核心方法:
参数介绍:三个参数全都
是固定写法!
   参数一:通过被增强对象获取类加载器
   参数二:通过被增强对象获取所有实现类的接口
   参数三:动态代理的处理类,用于对方法的增强
 代理图示:

 
2动态代理操作步骤

固定步骤:
    1、创建被增强对象【被代理对象】
    2、创建增强对象  【代理对象】
       2.1、通过被代理对象获取类加载器 
             被代理对象.getClass().getClassLoader()
       2.2、通过被代理对象获取其所有的接口 
             被代理对象.getClass().getInterfaces()
       2.3、创建一个处理类 【专门用来增强方法】
 动态代理执行简单过程:
动态代理只对接口里面的方法进行增强,实现类的不曾强!(我们实现动态代理压根儿不知道它的实现类)
3 解决request请求乱码问题:
案例代码:
//1.解决POST中文乱码
        request.setCharacterEncoding("utf-8")
        /*//2.使用装饰者设计模式解决GET请求中文乱码
        MyRequest req = new MyRequest((HttpServletRequest) request);
        //3.放行,如果后面没有其它的过滤器,那么访问目标资源文件,需要传递包装过后的request对象
        chain.doFilter(req, response);*/
       
        //4.使用动态代理设计模式解决GET请求中文乱码
        //5.创建一个被代理对象(直接强转得到)
        final HttpServletRequest req = (HttpServletRequest) request;
       
        //6.创建代理对象实例
        HttpServletRequest requestProxy = (HttpServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //只对getParameter方法增强
                if("getParameter".equals(method.getName())){
                    //只处理GET请求中文乱码
                    if("GET".equalsIgnoreCase(req.getMethod())){
                        //执行invoke方法,得到乱码的请求参数
                        //代理对象(requestProxy)调用被代理对象(req)里面的方法才执行
                        //执行它method.invoke(req, args)等价于执行getParameter();
                        String value = (String) method.invoke(req, args);
                        //解决乱码问题
                        value = new String(value.getBytes("iso8859-1"),"utf-8");
                        //如果是get请求,返回处理后的对象
                        return value;
                    }
                    //如果不是get请求,调用原来的方法
                    return method.invoke(req, args);
                }
                //如果是其它方法,也调用原来的方法
                return method.invoke(req, args);
            }
        });
        //7.放行,如果没哟其它过滤器,直接到目标资源文件
        chain.doFilter(requestProxy, response);
4 动态代理与静态代理区别
1、静态代理   代理的是类   创建一个增强类【代理类】
2、动态代理   代理的是对象 创建一个增强对象【代理对象】
 
  1. 静态代理(工作量极大)   
要实现所有接口中的所有方法全部实现。工作量极大
    需要知道具体的接口名字。通过class找所有接口。工作量极大
 
2、动态代理(灵活,工作量极小)    只需要被代理对象
5.总结(类加载器)
l 类加载器:类加载器是负责加载类的对象。将class文件(硬盘)加载到内存生成Class对象。
   所有的类加载器都是  java.lang.ClassLoader的子类
   

l 使用   .class.getClassLoader() 获得加载自己的类加载器
l 类加载器加载机制:全盘负责委托机制
   全盘负责:A类如果要使用B类(不存在),A类加载器C必须负责加载B类。
      

   委托机制:A类加载器如果要加载资源B,必须询问父类加载是否加载。
      如果加载,将直接使用。
      如果没有机制,自己再加载。
l 采用全盘负责委托机制保证一个class文件只会被加载一次,形成一个Class对象。
l 注意:
   如果一个class文件,被两个类加载器加载,将是两个对象。
      提示 com.andday.Hello 不能强制成 com.andday.Hello
              h.getClass() -->A                 h.getClass()  -->B
   自定义类加载,可以将一个class文件加载多次。
 
0 0
原创粉丝点击