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

}
相關文章
相關標籤/搜索