程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java中靜態代理的完成

java中靜態代理的完成

編輯:關於JAVA

java中靜態代理的完成。本站提示廣大學習愛好者:(java中靜態代理的完成)文章只能為提供參考,不一定能成為您想要的結果。以下是java中靜態代理的完成正文


靜態代理的完成

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

兩種靜態代理:
(1)jdk靜態代理,jdk靜態代理是由Java外部的反射機制來完成的,目的類基於一致的接口(InvocationHandler)
(2)cglib靜態代理,cglib靜態代理底層則是借助asm來完成的,cglib這種第三方類庫完成的靜態代理使用愈加普遍,且在效率上更有優勢。

次要使用的框架:
Spring中的AOP,Struts2中的阻攔器

詳細完成:


1、定義接口和完成類

package com.example.service;

public interface UserService {
    public String getName(int id);

    public Integer getAge(int id);
}
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靜態代理完成

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;
        }
    }
}
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通常被首選運用,由於它更快。

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;
    }
}
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++++++


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved