使用java中的反射实现简单的web请求解耦

因为最近都在写python,之前的笔记都保存在有道云里面。java的内容很少,但学了这么久,也算是一个机会做一个总结。

对于java中的一些高级特性,例如反射,动态代理等,我会一一写出用法和项目中大概用的场景(其实大部分框架以及搭好了),主要是给我自己总结一下

反射

  我们在学习一项技术的时候,一定要明白这项技术的使用场景,也就是说为什么会有这项技术的出现,是为了解决什么问题,反射的作用是在获取到类的名字的同时,jvm会new一个class对象

  jdk中这句话可以告诉我们class对象的产生

 类对象由Java虚拟机自动构建,因为加载了类,并且通过调用类加载器中的defineClass方法

  获取到这个class对象之后,我们就拥有这个类的字段,方法,甚至通过这个对象的名字动态的创建类的实例。单独看这个功能其实没什么用,因为直接把对象new出来也是一样的效果,但和其他东西结合一下就不一样了

和工厂模式结合

  有时候我们在做项目的时候,工厂模式根本不知道要创建具体哪一个类,例如

interface person{  
    public abstract void eat();  
}  
   
class student implements person{  
    public void eat(){  
        System.out.println("Apple");  
    }  
}  
   
class teacher implements person{  
    public void eat(){  
        System.out.println("Orange");  
    }  
} 

同样是实现了person接口,当这工厂模式返回实例,可能并不知道到底要哪个实例

class Factory{  
    public static person getInstance(String ClassName){  
        person p=null;  
        try{  
            p=(person)Class.forName(ClassName).newInstance();  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        return p;  
    }  
}  

这种时候使用反射可以动态的创建出实例,这样无论这个接口有多少个实现类,我们都不用自己去new,实现类与类的解耦

和继承集合

  其实,和上面的例子差不多,只不过上面反射动态创建实例,这个例子反射调用方法,在做web开发的时候,每一个servlet都要写doget,dopost的方法,所有的业务逻辑从这两个方法开始,为了解耦(其实是为了少写代码),我们可以自己写一个

baseservlet,这个servlet根据url的参数,调用对应的方法,

例如url请求  /product?method=delProFormCart 根据这个method参数,调用业务逻辑,附上代码

public class BaseServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        req.setCharacterEncoding("utf-8");
        /*
        * 这个this指代的调用该service的类
        * */
        Class clazz=this.getClass();
        String methodName=req.getParameter("method");
        try {
            Method method=clazz.getMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
            method.invoke(this,req,resp);

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }


    }

}
method.invoke(this,req,resp);
invoke这个方法有第一个参数是你调用方法本身类的实例,后面是改方法的参数,注意,反射的同时这个对象还是被创建了,因此实际上我debug看一下,反射执行的方法依旧是在那个类里面实现的

总结
  学动态代理的时候和反射老是搞不清楚,所以回头总结一下,反射并没有对类或者方法增强,只是调用。