java反射及使用其实现Springmvc @RequestMapping功能

1.java反射

jvm中使用Class对象描述类信息,每个具体的对象均可以获取对应的Class对象信息。每个类的信息都会保存着类名.class文件中,jvm在加载该文件后会生成一个Class对象,经过这个Class对象能够直接建立一个对象,也可查看类声明的属性、方法、修饰符号、继承的类和实现的接口信息等等。java

可经过如下方式获取class对象spring

Class bclass = boolean.class;
String string = new String();
Class sClass = string.getClass();
Object o = mapClass.newInstance();//经过class对象建立描述的类对象实例

Map<String,String> map = new HashMap();
Class mapClass = map.getClass();
System.out.println(mapClass.getCanonicalName()); //class对象信息的全路径
System.out.println(Modifier.toString(mapClass.getModifiers())); //class对象的修饰符
TypeVariable[] typeParameters = mapClass.getTypeParameters(); //class对象泛型信息
Type[] genericInterfaces = mapClass.getGenericInterfaces(); //class对象实现的接口
mapClass.getAnnotations(); //class对象的注解

Field age = studentClass.getDeclaredField("age"); //经过指定名称获取成员
Field[] declaredFields = studentClass.getDeclaredFields();//获取全部成员,包括private

Method getAgeMethod = studentClass.getDeclaredMethod("getAge"); //经过方法名获取方法对象
Method[] methods = studentClass.getDeclaredMethods(); //获取全部方法,包括private权限的,
Object invoke = getAgeMethod.invoke(student); //studnet.getAge();

Method setAgeMethod = studentClass.getDeclaredMethod("setAge");
setAgeMethod.invoke(student,23);

下面经过例子详细说明:mvc

//建立一个Student类
package com.xiayu.common.entity;

import java.util.Date;

public class Student {
    
    private String loginName;
    
    private String nickName;
    
    private Integer age;
    
    private Date birthday;
    
    public Student(){}
    
    public Student(String loginName,String nickName,Integer age,Date birthday){
        this.loginName = loginName;
        this.nickName = nickName;
        this.birthday = birthday;
        this.age = age;
    }
    
    public String getLoginName(){
        return  this.loginName;
    }
    
    public String getNickName(){
        return  this.nickName;
    }
    
    public Integer getAge(){
        return  this.age;
    }
    
    public Date getBirthday(){
        return this.birthday;
    }
    
}

经过反射获取类对象信息app

Logger logger = LoggerFactory.getLogger(ReflectTest.class);
Student student = new Student();
Class studentClass = Class.forName("com.xiayu.common.entity.Student");
Field age = studentClass.getDeclaredField("age"); //经过指定名称获取成员
Field[] declaredFields = studentClass.getDeclaredFields();//获取全部成员,包括private

Method getAgeMethod = studentClass.getDeclaredMethod("getAge"); //经过方法名获取方法对象
Method[] methods = studentClass.getDeclaredMethods(); //获取全部方法,包括private权限的,
Object invoke = getAgeMethod.invoke(student); //studnet.getAge();

Method setAgeMethod = studentClass.getDeclaredMethod("setAge"); //获取setAge方法对象
setAgeMethod.setAccessible(true); //设置可访问private方法
setAgeMethod.invoke(student,23);//==student.setAge(23)

2.springmvc @RequestMapping实现demo

定义@RequestMap注解jvm

package com.xiayu.common.controller;  
  
import java.lang.annotation.*;  
  
@Documented //使用javadoc能够自动生成文档信息  
@Target({ElementType.METHOD}) //描述该注解应用于什么地方,如方法上、类上、成员变量上、方法参数上等等  
@Retention(RetentionPolicy.RUNTIME)//定义注解的生命周期RetentionPolicy.RUNTIME .CLASS .SOURCE分别对应运行时 字节码 源码  
public @interface RequestMap {  
    String name() default "";  
    String value() default ""; 
}

定义DispatcherServlet,继承HttpServlet,获取全部请求,依据uri映射对应的处理方法Methodide

package com.xiayu.common.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@WebServlet(value = "/*",loadOnStartup = 1) // /*全部的请求都到此Servlet中,loadOnStartup 设置此Servlet优先加载
public class DispatcherServlet extends HttpServlet {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private Map<String,Method> map = new HashMap<>(); //map保存uri和对应的Method

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String requestURI = request.getRequestURI();//获取请求的url
        Method method = map.get(requestURI); //经过requestURI来找到要执行的方法
        Class declaringClass = method.getDeclaringClass(); //经过method获取声明该方法的类
        Object newInstance = declaringClass.newInstance(); //获取实例
        method.invoke(newInstance);//生成的实例,调用该方法,此处能够传入请求的参数
    }

    @Override
    public void init() throws ServletException {
        try {
            Class userClass = Class.forName("com.xiayu.common.controller.UserServlet");//这里userClass是写死的,能够经过扫描class文件夹获取到全部class文件名,而后再使用Class.forName()进行加载
            Method[] declaredMethods = userClass.getDeclaredMethods(); //获取userClass类对象的全部声明方法
            for (Method method:declaredMethods){
                if (method.isAnnotationPresent(RequestMap.class)){ //若是加了RequestMap的注解
                    RequestMap requestMap = method.getDeclaredAnnotation(RequestMap.class); //就将该方法加入到Map中,value为key,method为value,此处也能够将Method做为value,也能够将方法类的实例做为value,这样就保证类对象是单例的。
                    map.put(requestMap.value(),method); //put到map中
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

使用@RequestMapthis

package com.xiayu.common.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserServlet {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @RequestMap(name ="user login",value = "/getUserInfo")
    public void getUserInfo(){
        logger.info("getUserInfo");
    }
    
    @RequestMap(name = "change password",value = "/changePassword")
    public void changePassword(){
        logger.info("changePassword");
    }

}
相关文章
相关标签/搜索