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

Java動態(tài)代理的應(yīng)用詳解

 更新時間:2013年05月04日 14:27:32   作者:  
本篇文章介紹了,Java動態(tài)代理的應(yīng)用詳解,需要的朋友參考下

動態(tài)代理其實就是java.lang.reflect.Proxy類動態(tài)的根據(jù)您指定的所有接口生成一個class byte,該class會繼承Proxy類,并實現(xiàn)所有你指定的接口(您在參數(shù)中傳入的接口數(shù)組);然后再利用您指定的classloader將 class byte加載進系統(tǒng),最后生成這樣一個類的對象,并初始化該對象的一些值,如invocationHandler,以即所有的接口對應(yīng)的Method成員。 初始化之后將對象返回給調(diào)用的客戶端。這樣客戶端拿到的就是一個實現(xiàn)你所有的接口的Proxy對象。請看實例分析:

復制代碼 代碼如下:

package com.fans.common.proxy;

public interface BusinessProcessor {
  public void processBusiness();
}


復制代碼 代碼如下:

package com.fans.common.proxy;
/**
 * 業(yè)務(wù)處理類
 * @author fanshadoop
 *
 */
public class BusinessProcessorImpl implements BusinessProcessor {

 @Override
 public void processBusiness() {
  System.out.println("processing business.....");

 }

}


復制代碼 代碼如下:

package com.fans.common.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * 業(yè)務(wù)代理類
 * @author fanshadoop
 *
 */
public class BusinessProcessorHandler implements InvocationHandler {

 private Object target = null;

 BusinessProcessorHandler(Object target) {
  this.target = target;
 }

 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  System.out
    .println("You can do something here before process your business");
  Object result = method.invoke(target, args);
  System.out
    .println("You can do something here after process your business");
  return result;
 }

}


復制代碼 代碼如下:

package com.fans.common.proxy;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;

public class Test {

 /**
  * @param args
  */
 public static void main(String[] args) {
  BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
  BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
  BusinessProcessor bp = (BusinessProcessor) Proxy.newProxyInstance(
    bpimpl.getClass().getClassLoader(), bpimpl.getClass()
      .getInterfaces(), handler);
  bp.processBusiness();

  System.out.println(bp.getClass().getName());
  printClassDefinition(bp.getClass());
 }

 public static String getModifier(int modifier) {
  String result = "";
  switch (modifier) {
  case Modifier.PRIVATE:
   result = "private";
  case Modifier.PUBLIC:
   result = "public";
  case Modifier.PROTECTED:
   result = "protected";
  case Modifier.ABSTRACT:
   result = "abstract";
  case Modifier.FINAL:
   result = "final";
  case Modifier.NATIVE:
   result = "native";
  case Modifier.STATIC:
   result = "static";
  case Modifier.SYNCHRONIZED:
   result = "synchronized";
  case Modifier.STRICT:
   result = "strict";
  case Modifier.TRANSIENT:
   result = "transient";
  case Modifier.VOLATILE:
   result = "volatile";
  case Modifier.INTERFACE:
   result = "interface";
  }
  return result;
 }

 public static void printClassDefinition(Class clz) {

  String clzModifier = getModifier(clz.getModifiers());
  if (clzModifier != null && !clzModifier.equals("")) {
   clzModifier = clzModifier + " ";
  }
  String superClz = clz.getSuperclass().getName();
  if (superClz != null && !superClz.equals("")) {
   superClz = "extends " + superClz;
  }
  Class[] interfaces = clz.getInterfaces();
  String inters = "";
  for (int i = 0; i < interfaces.length; i++) {
   if (i == 0) {
    inters += "implements ";
   }
   inters += interfaces[i].getName();
  }
  System.out.println(clzModifier + clz.getName() + " " + superClz + " "
    + inters);
  System.out.println("{");
  Field[] fields = clz.getDeclaredFields();
  for (int i = 0; i < fields.length; i++) {
   String modifier = getModifier(fields[i].getModifiers());
   if (modifier != null && !modifier.equals("")) {
    modifier = modifier + " ";
   }
   String fieldName = fields[i].getName();
   String fieldType = fields[i].getType().getName();
   System.out.println("    " + modifier + fieldType + " " + fieldName
     + ";");
  }

  System.out.println();

  Method[] methods = clz.getDeclaredMethods();
  for (int i = 0; i < methods.length; i++) {
   Method method = methods[i];

   String modifier = getModifier(method.getModifiers());
   if (modifier != null && !modifier.equals("")) {
    modifier = modifier + " ";
   }
   String methodName = method.getName();
   Class returnClz = method.getReturnType();
   String retrunType = returnClz.getName();

   Class[] clzs = method.getParameterTypes();
   String paraList = "(";
   for (int j = 0; j < clzs.length; j++) {
    paraList += clzs[j].getName();
    if (j != clzs.length - 1) {
     paraList += ", ";
    }
   }
   paraList += ")";
   clzs = method.getExceptionTypes();
   String exceptions = "";
   for (int j = 0; j < clzs.length; j++) {
    if (j == 0) {
     exceptions += "throws ";
    }
    exceptions += clzs[j].getName();
    if (j != clzs.length - 1) {
     exceptions += ", ";
    }
   }
   exceptions += ";";
   String methodPrototype = modifier + retrunType + " " + methodName
     + paraList + exceptions;

   System.out.println("    " + methodPrototype);
  }
  System.out.println("}");
 }
}


運行結(jié)果:
復制代碼 代碼如下:

You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0
$Proxy0 extends java.lang.reflect.Proxy implements com.fans.common.proxy.BusinessProcessor
{
    java.lang.reflect.Method m1;
    java.lang.reflect.Method m3;
    java.lang.reflect.Method m0;
    java.lang.reflect.Method m2;

    boolean equals(java.lang.Object);
    java.lang.String toString();
    int hashCode();
    void processBusiness();
}


類BusinessProcessorHandler實現(xiàn)了InvocationHandler接口的invoke方法,這個類就是Proxy最終調(diào)用固定接口方法。

很明顯,Proxy.newProxyInstance方法會做如下幾件事:
    1,根據(jù)傳入的第二個參數(shù)interfaces動態(tài)生成一個類,實現(xiàn)interfaces中的接口,該例中即BusinessProcessor接口的processBusiness方法。并且繼承了Proxy類,重寫了hashcode,toString,equals等三個方法。具體實現(xiàn)可參看 ProxyGenerator.generateProxyClass(...); 該例中生成了$Proxy0類
    2,通過傳入的第一個參數(shù)classloder將剛生成的類加載到j(luò)vm中。即將$Proxy0類load
    3,利用第三個參數(shù),調(diào)用$Proxy0的$Proxy0(InvocationHandler)構(gòu)造函數(shù) 創(chuàng)建$Proxy0的對象,并且用interfaces參數(shù)遍歷其所有接口的方法,并生成Method對象初始化對象的幾個Method成員變量
    4,將$Proxy0的實例返回給客戶端。
現(xiàn)在好了。我們再看客戶端怎么調(diào)就清楚了。
    1,客戶端拿到的是$Proxy0的實例對象,由于$Proxy0繼承了BusinessProcessor,因此轉(zhuǎn)化為BusinessProcessor沒任何問題。
         BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
    2,bp.processBusiness();
         實際上調(diào)用的是$Proxy0.processBusiness();那么$Proxy0.processBusiness()的實現(xiàn)就是通過InvocationHandler去調(diào)用invoke方法啦!

相關(guān)文章

  • spring AOP自定義注解方式實現(xiàn)日志管理的實例講解

    spring AOP自定義注解方式實現(xiàn)日志管理的實例講解

    下面小編就為大家分享一篇spring AOP自定義注解方式實現(xiàn)日志管理的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • 基于Lombok集成springboot遇到的坑

    基于Lombok集成springboot遇到的坑

    這篇文章主要介紹了Lombok集成springboot遇到的坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringBoot整合minio服務(wù)的示例代碼

    SpringBoot整合minio服務(wù)的示例代碼

    本文主要介紹了SpringBoot整合minio服務(wù)的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • Java8 Predicate花樣用法詳解

    Java8 Predicate花樣用法詳解

    本文主要介紹了Java 8 Predicate花樣用法詳解,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 淺談JAVA設(shè)計模式之代理模式

    淺談JAVA設(shè)計模式之代理模式

    這篇文章主要介紹了JAVA設(shè)計模式之代理模式的的相關(guān)資料,文中代碼非常詳細,供大家參考和學習,感興趣的朋友可以了解下
    2020-06-06
  • 在Spring Boot框架中使用AOP的正確姿勢

    在Spring Boot框架中使用AOP的正確姿勢

    aop是spring的兩大功能模塊之一,功能非常強大,為解耦提供了非常優(yōu)秀的解決方案。下面這篇文章主要給大家介紹了如何在Spring Boot框架中使用AOP的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-08-08
  • 帶你用Java方法輕松實現(xiàn)樹的同構(gòu)

    帶你用Java方法輕松實現(xiàn)樹的同構(gòu)

    給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構(gòu)”的。例如圖1給出的兩棵樹就是同構(gòu)的,因為我們把其中一棵樹的結(jié)點A、B、G的左右孩子互換后,就得到另外一棵樹
    2021-06-06
  • 淺析java 10中的var關(guān)鍵字用法

    淺析java 10中的var關(guān)鍵字用法

    2018年3月20日,Oracle發(fā)布java10。java10為java帶來了很多新特性。這篇文章主要介紹了Java 10 var關(guān)鍵字詳解和示例教程,需要的朋友可以參考下
    2018-10-10
  • SpringBoot項目打包成jar后獲取classpath下文件失敗的解決

    SpringBoot項目打包成jar后獲取classpath下文件失敗的解決

    這篇文章主要介紹了SpringBoot項目打包成jar后獲取classpath下文件失敗的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 解決java 分割字符串成數(shù)組時,小圓點不能直接進行分割的問題

    解決java 分割字符串成數(shù)組時,小圓點不能直接進行分割的問題

    這篇文章主要介紹了解決java 分割字符串成數(shù)組時,小圓點不能直接進行分割的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12

最新評論