国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java中動態代理的實現

java中動態代理的實現

2020-07-22 14:49LSPZ Java教程

本篇文章主要介紹了Java中兩種動態代理的實現:jdk動態代理;cglib動態代理。具有一定的參考價值,下面跟著小編一起來看下吧

動態代理的實現

使用的模式:代理模式。

代理模式的作用是:為其他對象提供一種代理以控制對這個對象的訪問。類似租房的中介。

兩種動態代理:

(1)jdk動態代理,jdk動態代理是由Java內部的反射機制來實現的,目標類基于統一的接口(InvocationHandler)

(2)cglib動態代理,cglib動態代理底層則是借助asm來實現的,cglib這種第三方類庫實現的動態代理應用更加廣泛,且在效率上更有優勢。

主要應用的框架:

Spring中的AOP,Struts2中的攔截器

具體實現:

1、定義接口和實現類

java" id="highlighter_107295">
?
1
2
3
4
5
package com.example.service;
public interface UserService {
  public String getName(int id);
  public Integer getAge(int id);
}
?
1
2
3
4
5
6
7
8
9
10
11
12
package com.example.service.impl;
import com.example.service.UserService;
public class UserServiceImpl implements UserService {
  public String getName(int id) {
    System.out.println("------getName------");
    return "cat";
  }
  public Integer getAge(int id) {
    System.out.println("------getAge------");
    return 10;
  }
}

2、jdk動態代理實現

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.example.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyInvocationHandler implements InvocationHandler {
  private Object target;
  /**
   * 綁定委托對象并返回一個代理類
   *
   * @param target
   * @return
   */
  public Object bind(Object target) {
    this.target = target;
    //取得代理對象
    return Proxy.newProxyInstance(target.getClass().getClassLoader(),
        target.getClass().getInterfaces(), this);  //要綁定接口(這是一個缺陷,cglib彌補了這一缺陷)
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if ("getName".equals(method.getName())) {
      System.out.println("------before " + method.getName() + "------");
      Object result = method.invoke(target, args);
      System.out.println("------after " + method.getName() + "------");
      return result;
    } else {
      Object result = method.invoke(target, args);
      return result;
    }
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.example.jdk;
 
import com.example.service.UserService;
import com.example.service.impl.UserServiceImpl;
 
/**
 * 測試類
 */
public class RunJDK {
  public static void main(String[] args) {
    MyInvocationHandler proxy = new MyInvocationHandler();
    UserService userServiceProxy = (UserService) proxy.bind(new UserServiceImpl());
    System.out.println(userServiceProxy.getName(1));
    System.out.println(userServiceProxy.getAge(1));
  }
}

運行結果:

------before getName------
------getName------
------after getName------
cat
------getAge------
10

3、cglib動態代理實現:

JDK的動態代理機制只能代理實現了接口的類,而不能實現接口的類就不能實現JDK的動態代理,cglib是針對類來實現代理的,他的原理是對指定的目標類生成一個子類,并覆蓋其中方法實現增強,但因為采用的是繼承,所以不能對final修飾的類進行代理。

CGLIB的核心類:

net.sf.cglib.proxy.Enhancer – 主要的增強類
net.sf.cglib.proxy.MethodInterceptor – 主要的方法攔截類,它是Callback接口的子接口,需要用戶實現
net.sf.cglib.proxy.MethodProxy – JDK的java.lang.reflect.Method類的代理類,可以方便的實現對源對象方法的調用。

net.sf.cglib.proxy.MethodInterceptor接口是最通用的回調(callback)類型,它經常被基于代理的AOP用來實現攔截(intercept)方法的調用。這個接口只定義了一個方法
public Object intercept(Object object, java.lang.reflect.Method method,
Object[] args, MethodProxy proxy) throws Throwable;

第一個參數是代理對像,第二和第三個參數分別是攔截的方法和方法的參數。原來的方法可能通過使用java.lang.reflect.Method對象的一般反射調用,或者使用 net.sf.cglib.proxy.MethodProxy對象調用。net.sf.cglib.proxy.MethodProxy通常被首選使用,因為它更快。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.example.cglib;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGLIBProxy implements MethodInterceptor {
  private Object target;
  /**
   * 創建代理對象
   *
   * @param target
   * @return
   */
  public Object getInstance(Object target) {
    this.target = target;
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(this.target.getClass());
    // 回調方法
    enhancer.setCallback(this);
    // 創建代理對象
    return enhancer.create();
  }
  @Override
  public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    System.out.println("++++++before " + methodProxy.getSuperName() + "++++++");
    System.out.println(method.getName());
    Object result = methodProxy.invokeSuper(o, objects);
    System.out.println("++++++after " + methodProxy.getSuperName() + "++++++");
    return result;
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.cglib;
import com.example.service.UserService;
import com.example.service.impl.UserServiceImpl;
/**
 * 測試CGLIB
 */
public class RunCGLIB {
  public static void main(String[] args) {
    CGLIBProxy cglibProxy = new CGLIBProxy();
    UserService userService = (UserService) cglibProxy.getInstance(new UserServiceImpl());
    userService.getName(1);
    userService.getAge(1);
  }
}

運行結果:

++++++before CGLIB$getName$0++++++
getName
------getName------
++++++after CGLIB$getName$0++++++
++++++before CGLIB$getAge$1++++++
getAge
------getAge------
++++++after CGLIB$getAge$1++++++

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持服務器之家!

原文鏈接:http://www.cnblogs.com/lspz/p/6237378.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 美女毛片 | 国产一区二区在线免费观看 | 久久午夜视频 | 国产精品久久久久久久久久 | 国产精品久久精品 | 亚洲一区二区三区 | 成人精品视频 | 日比视频网站 | 黄色免费av| 中文字幕日韩欧美 | 成人在线一区二区 | 欧美一区永久视频免费观看 | 成人在线一区二区 | 日韩免费高清视频 | 国产黄 | 精品久久久久久久久久久久久久 | 91污视频 | 国产精品视频一二三 | 精品国产一级 | 中国黄色一级视频 | 日韩午夜激情视频 | 偷拍一区二区三区 | 欧美黄色片 | 蜜桃tv一区二区三区 | 伊人网网站| 免费的一级毛片 | 欧美一区二区三区黄 | 国产精品99久久免费观看 | 在线中文字幕av | 国产日韩欧美在线观看 | 亚洲精品午夜 | 91久久在线 | 天天操天天干天天 | 在线三级电影 | 依人在线 | 亚洲二区在线 | 国产精品99 | 成人激情在线观看 | 久久久久久av | 亚洲日本中文字幕 | 日韩久久精品一区二区 |