欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java 反射和動態(tài)代理詳解及實例代碼

 更新時間:2016年09月30日 14:19:18   作者:夏中偉  
這篇文章主要介紹了java 反射和動態(tài)代理詳解及實例代碼的相關資料,需要的朋友可以參考下

一、java中的反射

1.通過反射加載類的屬性和方法實例代碼:

/**
     * java.lang.Class 是反射的源頭
     * 我們創(chuàng)建了一個類,通過編譯(javac.exe)生成對應的class文件,之后我們通過java.exe加載(jvm的類加載器加載)此class文件
     * 此class文件加載到內存后,就是一個運行時類,存在緩存區(qū),這個運行時類本事就是一個Class的實例
     * 每一個運行時類只加載一次,
     */
    Class<StudentExam> clazz = StudentExam.class;
    StudentExam studentExam = clazz.newInstance();
    System.err.println(studentExam);
     
    System.out.println(clazz);
    // Field field = clazz.getField("id"); // 通過屬性調用運行時類的指定屬性:屬性是public類型
    Field field = clazz.getDeclaredField("id"); // 屬性是非public 類型
    Field[] fields = clazz.getDeclaredFields(); // 獲取運行時類本身(父類不行)所有聲明的屬性,父類使用clazz.getFields();
    for (Field field2 : fields) {
      int i = field2.getModifiers();
      String type = Modifier.toString(i);// 獲取字段屬性的數據類型
      System.out.println(type);
    }
    field.setAccessible(true);
    field.set(studentExam, 11);
    System.err.println(studentExam.getId());
     
    // 通過反射調用運行時類的指定方法
    Method method = clazz.getMethod("setId", Integer.class);
    method.invoke(studentExam, 123); // 調用運行時類的指定方法
    Method[] methods = clazz.getMethods(); // 獲取所有運行時類及其父類中所有聲明為public的方法
    Method[] methods2 = clazz.getDeclaredMethods();// 獲取運行時類本身類中聲明的方法
    for (Method method2 : methods) {
      System.out.println(method2.getName());
    }
     
    // * 通過對象的getClass()方法獲取對象的運行時類,
    Exam exam = new Exam();
    Class clazzExam = exam.getClass();

2.類加載器ClassLoader

/**
   * Description:類加載器,加載xx.properties文件,并讀取數據
   * @param
   * @author xiazhongwei
   * @data 2016年9月29日:下午5:32:56
   * @return
   */
  public void classLoader() throws IOException {
    //方法一、從當前工程下加載
    ClassLoader loader = this.getClass().getClassLoader();
    // 路徑是包下寫:com\\able\\onlineExam\\resources\\config.properties
    InputStream inStream = loader.getResourceAsStream("config.properties");
    // 方法二、從指定的路徑下加載文件
    // FileInputStream fileInputStream = new FileInputStream(new File("config.properties"));
     
    Properties properties = new Properties();
    properties.load(inStream);
    // properties.load(fileInputStream);
    String prop = properties.getProperty("domain");
    System.out.println(prop);
  }

3.動態(tài)代理

靜態(tài)代理:代理類和目標對象的類型都是在編譯期間確定下來,不利于程序的擴展。同時每個代理類只能為一個接口服務,這樣一來程序開發(fā)中必然產生過多的代理。

動態(tài)代理:客戶通過代理類來調用其他對象的方法,并且是在程序運行時,根據需要動態(tài)創(chuàng)建目標類的代理對象。

代理設計模式的原理:

使用一個代理將對象包裝起來,然后用該代理對象取代原始對象,任何對原始對象的調用都要通過代理,代理對象決定的那個是否以及何時將方法調用

package com.test.junit;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
public class ProxyTest {
 
  public static void main(String[] args) {
    RealSubject realSubject = new RealSubject();
    MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
    Object object = myInvocationHandler.bind(realSubject);
    Subject subject = (Subject) object;
    subject.action();
  }
}
// 動態(tài)代理的使用
interface Subject{
  void action();
}
// 被代理類
class RealSubject implements Subject{
 
  @Override
  public void action() {
 
    System.out.println("我是被代理類,記得執(zhí)行我哦。。。。");
  }
   
}
 
class MyInvocationHandler implements InvocationHandler{
 
  Object object;// 實現了接口的被代理類的對象的聲明
  /**
   * Description:①給被代理的對象實例化 ②返回一個代理類對象
   * @param
   * @author xiazhongwei
   * @data 2016年9月29日:下午4:13:43
   * @return
   */
  public Object bind(Object object){
    this.object = object;
    return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
  }
  /**
   * 當通過代理類的對象發(fā)起對被重寫的方法的調用時,都會轉化為對如下的invok方法的調用
   */
  @Override
  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {
    Object returnObject = method.invoke(object, args);
    return returnObject;
  }
}

4.動態(tài)代理與AOP

 示例一、

package com.atguigu.spring.aop;
 
public interface ArithmeticCalculator {
  int add(int i, int j);
  int sub(int i, int j);
   
  int mul(int i, int j);
  int div(int i, int j);
}
 package com.atguigu.spring.aop;
 
import org.springframework.stereotype.Component;
 
@Component("arithmeticCalculator")
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
 
  @Override
  public int add(int i, int j) {
    int result = i + j;
    return result;
  }
 
  @Override
  public int sub(int i, int j) {
    int result = i - j;
    return result;
  }
 
  @Override
  public int mul(int i, int j) {
    int result = i * j;
    return result;
  }
 
  @Override
  public int div(int i, int j) {
    int result = i / j;
    return result;
  }
 
}
 package com.atguigu.spring.aop;
 
public class ArithmeticCalculatorLoggingImpl implements ArithmeticCalculator {
 
  @Override
  public int add(int i, int j) {
    System.out.println("The method add begins with [" + i + "," + j + "]");
    int result = i + j;
    System.out.println("The method add ends with " + result);
    return result;
  }
 
  @Override
  public int sub(int i, int j) {
    System.out.println("The method sub begins with [" + i + "," + j + "]");
    int result = i - j;
    System.out.println("The method sub ends with " + result);
    return result;
  }
 
  @Override
  public int mul(int i, int j) {
    System.out.println("The method mul begins with [" + i + "," + j + "]");
    int result = i * j;
    System.out.println("The method mul ends with " + result);
    return result;
  }
 
  @Override
  public int div(int i, int j) {
    System.out.println("The method div begins with [" + i + "," + j + "]");
    int result = i / j;
    System.out.println("The method div ends with " + result);
    return result;
  }
 
}
  
package com.atguigu.spring.aop;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
 
public class ArithmeticCalculatorLoggingProxy {
   
  //要代理的對象
  private ArithmeticCalculator target;
   
  public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {
    super();
    this.target = target;
  }
 
  //返回代理對象
  public ArithmeticCalculator getLoggingProxy(){
    ArithmeticCalculator proxy = null;
    // 代理對象有哪一個類加載器負責加載
    ClassLoader loader = target.getClass().getClassLoader();
    // 代理對象的類型,即其中有哪些方法
    Class [] interfaces = new Class[]{ArithmeticCalculator.class};
    // 當調用代理對象的其中方法時,執(zhí)行下面的代碼
    InvocationHandler h = new InvocationHandler() {
      /**
       * proxy: 代理對象。 一般不使用該對象
       * method: 正在被調用的方法
       * args: 調用方法傳入的參數
       */
      @Override
      public Object invoke(Object proxy, Method method, Object[] args)
          throws Throwable {
        // 在方法內部不會直接調用proxy對象的某個方法,proxy.toString()會造成死循環(huán)調用invoke方法
        String methodName = method.getName();
        //打印日志
        System.out.println("[before] The method " + methodName + " begins with " + Arrays.asList(args));
         
        //調用目標方法
        Object result = null;
         
        try {
          //前置通知
          result = method.invoke(target, args);
          //返回通知, 可以訪問到方法的返回值
        } catch (NullPointerException e) {
          e.printStackTrace();
          //異常通知, 可以訪問到方法出現的異常
        }
         
        //后置通知. 因為方法可以能會出異常, 所以訪問不到方法的返回值
         
        //打印日志
        System.out.println("[after] The method ends with " + result);
         
        return result;
      }
    };
     
    /**
     * loader: 代理對象使用的類加載器。
     * interfaces: 指定代理對象的類型. 即代理代理對象中可以有哪些方法.
     * h: 當具體調用代理對象的方法時, 應該如何進行響應, 實際上就是調用 InvocationHandler 的 invoke 方法
     */
    proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
     
    return proxy;
  }
}
  

package com.atguigu.spring.aop;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Main {
   
  public static void main(String[] args) {
    // ArithmeticCalculator arithmeticCalculator = new ArithmeticCalculatorImpl();
    ArithmeticCalculator arithmeticCalculator = new ArithmeticCalculatorLoggingImpl();
     
    arithmeticCalculator = new ArithmeticCalculatorLoggingProxy(arithmeticCalculator).getLoggingProxy();
     
    int result = arithmeticCalculator.add(11, 12);
    System.out.println("result:" + result);
     
    result = arithmeticCalculator.div(21, 3);
    System.out.println("result:" + result);
     
  }
   
}

  示例二、

package com.test.junit;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
public class ProxyTest {
 
  public static void main(String[] args) {
    RealSubject realSubject = new RealSubject();
    MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
    Object object = myInvocationHandler.bind(realSubject);
    Subject subject = (Subject) object;
    subject.action();
  }
}
// 動態(tài)代理的使用
interface Subject{
  void action();
}
// 被代理類
class RealSubject implements Subject{
 
  @Override
  public void action() {
 
    System.out.println("我是被代理類,記得執(zhí)行我哦。。。。");
  }
   
}
 
class MyInvocationHandler implements InvocationHandler{
 
  Object object;// 實現了接口的被代理類的對象的聲明
  /**
   * Description:①給被代理的對象實例化 ②返回一個代理類對象
   * @param
   * @author xiazhongwei
   * @data 2016年9月29日:下午4:13:43
   * @return
   */
  public Object bind(Object object){
    this.object = object;
    return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
  }
  /**
   * 當通過代理類的對象發(fā)起對被重寫的方法的調用時,都會轉化為對如下的invok方法的調用
   */
  @Override
  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {
    Object returnObject = method.invoke(object, args);
    return returnObject;
  }
}



感謝閱讀此文,希望能幫助到大家,謝謝大家對本站的支持!

相關文章

  • Java基礎之垃圾回收機制詳解

    Java基礎之垃圾回收機制詳解

    這篇文章主要介紹了Java基礎之垃圾回收機制詳解,文中有非常詳細的代碼示例,對正在學習java基礎的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java文件基本操作總結

    Java文件基本操作總結

    今天給大家?guī)淼氖顷P于Java基礎的相關知識,文章圍繞著Java文件操作展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • spring boot基于注解的聲明式事務配置詳解

    spring boot基于注解的聲明式事務配置詳解

    這篇文章主要介紹了spring boot基于注解的聲明式事務配置詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 詳解Java的初始化與清理

    詳解Java的初始化與清理

    這篇文章主要介紹了Java的初始化與清理,文中示例代碼非常詳細,幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • Netty網絡編程零基礎入門

    Netty網絡編程零基礎入門

    Netty是一個異步的、基于事件驅動的網絡應用框架,用于快速開發(fā)可維護、高性能的網絡服務器和客戶端,如果你還不了解它的使用,就趕快繼續(xù)往下看吧
    2022-08-08
  • 詳解Java中字符流與字節(jié)流的區(qū)別

    詳解Java中字符流與字節(jié)流的區(qū)別

    這篇文章主要為大家詳細介紹了Java中字符流與字節(jié)流的區(qū)別,這兩個的概念易混淆,今天就為大家進行詳細區(qū)分,感興趣的小伙伴們可以參考一下
    2016-04-04
  • Java 值傳遞和引用傳遞詳解及實例代碼

    Java 值傳遞和引用傳遞詳解及實例代碼

    這篇文章主要介紹了 Java 值傳遞和引用傳遞詳解及實例代碼的相關資料,需要的朋友可以參考下
    2017-03-03
  • intellij idea如何配置網絡代理

    intellij idea如何配置網絡代理

    intellij idea所在的這臺電腦本身上不了網,要通過代理上網,那么intellij idea怎么設置代理上網呢?今天通過本文給大家分享intellij idea如何配置網絡代理,感興趣的朋友一起看看吧
    2023-10-10
  • 淺析java的foreach循環(huán)

    淺析java的foreach循環(huán)

    foreach語句是java5之后的新特征之一,在循環(huán)遍歷數組、集合方面更加簡潔,有需要的朋友可以參考一下
    2013-12-12
  • 將JavaDoc注釋生成API文檔的操作

    將JavaDoc注釋生成API文檔的操作

    這篇文章主要介紹了將JavaDoc注釋生成API文檔的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評論