1. 程式人生 > >spring AOP 動態代理 jkd動態代理和cglib動態代理 hibernate使用cglib延遲載入

spring AOP 動態代理 jkd動態代理和cglib動態代理 hibernate使用cglib延遲載入

spring 的AOP 實現 可以使用jdk的動態代理,也可以使用cglib的動態代理 先說下兩者區別:
靜態代理:代理之前就已經知道了代理者和被代理者
動態代理:代理之前並不清楚,在執行時使用反射機制動態生成代理類的位元組碼 無需我們手動編寫它的原始碼
jdk動態代理:java.lang.reflect 包中的Proxy類,InvocationHandler 介面提供了生成動態代理類的能力。它必須有被代理物件的介面和實現類,ciglib不需要介面,簡單的說 jkd動態代理針對介面,而cglib動態代理針對的是類 比JDK快,但載入cglib的時間比jdk反射的時間長,開發的過程中,如果是反覆動態生成新的代理類推薦用 JDK 自身的反射,反之用 cglib。

spring AOP的實現 既可以編寫介面使用jdk動態代理實現,也可以使用cglib來進行實現

對於hibernate使用cglib延遲載入,在load()的時候,cglib會生成一個數據庫實體類的代理類,此代理類開始的時候裡面的屬性值是null,只有當真正請求資料,如user.getName()的時候,這個代理類就會去資料庫裡查詢出具體的值(通過cglib的回撥機制),然後載入到代理類對應的屬性中,最後返回給給呼叫者。

以下為一個轉載的例項:

/**
*使用類
*/
public class MyClass { 
public void method() { 
        System.out.println("MyClass.method()"
); } public void method2() { System.out.println("MyClass.method2()"); } } /** *使用代理 */ import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodProxy; import net.sf.cglib.proxy.MethodInterceptor; public class Main { public static void
main(String[] args) { Enhancer enhancer = new Enhancer(); //在這代理了 enhancer.setSuperclass(MyClass.class); enhancer.setCallback( new MethodInterceptorImpl() ); // 創造 代理 (動態擴充套件了MyClass類) MyClass my = (MyClass)enhancer.create(); my.method(); } private static class MethodInterceptorImpl implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(method); proxy.invokeSuper(obj, args); return null; } } } /** *新增方法過濾 */ import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodProxy; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.NoOp; import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.CallbackFilter; public class Main2 { public static void main(String[] args) { Callback[] callbacks = new Callback[] { new MethodInterceptorImpl(), NoOp.INSTANCE }; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MyClass.class); enhancer.setCallbacks( callbacks ); //新增 方法過濾器 返回1為不執行 2 為執行 enhancer.setCallbackFilter( new CallbackFilterImpl() ); MyClass my = (MyClass)enhancer.create(); my.method(); my.method2(); } private static class CallbackFilterImpl implements CallbackFilter { public int accept(Method method) { if ( method.getName().equals("method2") ) { return 1; } else { return 0; } } } private static class MethodInterceptorImpl implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(method); return proxy.invokeSuper(obj, args); } } }

下面貼下在imooc上自己寫的幾個小例子:
具體可點選:

jdk動態代理的簡單實現:

package proxy.dynamicProxy.jdk;

import java.util.Random;

/**
 * 需要代理的具體類繼承介面
 */
public class Car implements Moveable {

    @Override
    public void move() {
        //實現開車
        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽車行駛中....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
########################################
package proxy.dynamicProxy.jdk;

/**
 *jdk實現動態代理模式,必須使用介面
 */
public interface Moveable {
    void move();
}
########################################
package proxy.dynamicProxy.jdk;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 代理者,必須整合InvocationHandler 實現invoke方法
 */
public class TimeHandler implements InvocationHandler {

    public TimeHandler(Object target) {
        super();
        this.target = target;
    }

    //代理物件
    private Object target;

    /*
     * 只能代理實現了介面的類,沒有實現介面的類不能實現JDK動態代理
     * 引數:
     * proxy  被代理物件
     * method  被代理物件的方法
     * args 方法的引數
     * 
     * 返回值:
     * Object  方法的返回值
     * */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        long starttime = System.currentTimeMillis();
        System.out.println("汽車開始行駛....");
        method.invoke(target);
        long endtime = System.currentTimeMillis();
        System.out.println("汽車結束行駛....  汽車行駛時間:" 
                + (endtime - starttime) + "毫秒!");
        return null;
    }

}
#####################################
package proxy.dynamicProxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;


public class Test {

    /**
     * JDK動態代理測試類
     */
    public static void main(String[] args) {
        Car car = new Car();
        InvocationHandler h = new TimeHandler(car);
        Class<?> cls = car.getClass();
        /**
         * loader  類載入器
         * interfaces  實現介面
         * h InvocationHandler 呼叫處理者
         */
        Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(),
                                                cls.getInterfaces(), h);
        m.move();
    }

}

cglib動態代理簡單實現:

package proxy.dynamicProxy.cglib;

public class Train {

    public void move(){
        System.out.println("火車行駛中...");
    }
}
##########################################
package proxy.dynamicProxy.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxy implements MethodInterceptor {

    private Enhancer enhancer = new Enhancer();//例項化強化劑物件

    public Object getProxy(Class clazz){
        //設定建立子類的類
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);

        return enhancer.create();
    }

    /**
     * 針對類來實現代理,先為目標類生產一個子類,通過方法攔截技術攔截所有父類方法的呼叫
     * 攔截所有目標類(父類)方法的呼叫
     * obj  目標類的例項
     * m   目標方法的反射物件
     * args  方法的引數
     * proxy代理類的例項
     */
    @Override
    public Object intercept(Object obj, Method m, Object[] args,
            MethodProxy proxy) throws Throwable {
        System.out.println("日誌開始...");
        //代理類呼叫父類的方法
        proxy.invokeSuper(obj, args);
        System.out.println("日誌結束...");
        return null;
    }

}
##################################
package proxy.dynamicProxy.cglib;

import proxy.dynamicProxy.cglib.CglibProxy;

public class Client {

    /**
     * @param args
     */
    public static void main(String[] args) {

        CglibProxy proxy = new CglibProxy();
        Train t = (Train)proxy.getProxy(Train.class);
        t.move();
    }

}

相關推薦

代理模式】jdkcglib動態代理實現的區別

jdk和cglib動態代理實現的區別 1、jdk動態代理生成的代理類和委託類實現了相同的介面; 2、cglib動態代理中生成的位元組碼更加複雜,生成的代理類是委託類的子類,且不能處理被final關鍵字

spring AOP 動態代理 jkd動態代理cglib動態代理 hibernate使用cglib延遲載入

spring 的AOP 實現 可以使用jdk的動態代理,也可以使用cglib的動態代理 先說下兩者區別: 靜態代理:代理之前就已經知道了代理者和被代理者 動態代理:代理之前並不清楚,在執行時使用反射機制動態生成代理類的位元組碼 無需我們手動編寫它的原始碼

Spring底層AOP的原理示例(JDK動態代理cglib動態代理

1 JDK動態代理(必須要有介面) 介面 package com.itykd.dao; public interface UserDao { void save(); void update(); void find(); void delete(); } 實現

Spring AOP之---基於JDK動態代理CGLib動態代理AOP實現

AOP(面向切面程式設計)是OOP的有益補充,它只適合那些具有橫切邏輯的應用場合,如效能監測,訪問控制,事物管理,日誌記錄等。至於怎麼理解橫切邏輯,敲完例項程式碼也就明白了。 為什麼要使用AOP,舉個栗子:需要監測一些方法的執行所消耗的時間,在每個方法開始

Spring AOP中的JDKCGLib動態代理哪個效率更高?

一、背景 今天有小夥伴面試的時候被問到:Spring AOP中JDK 和 CGLib動態代理哪個效率更高? 二、基本概念 首先,我們知道Spring AOP的底層實現有兩種方式:一種是JDK動態代理,另一種是CGLib的方式。 自Java 1.3以後

Spring AOP底層實現- JDK動態代理CGLIB動態代理

Spring AOP是執行時織入的,那麼執行時織入到底是怎麼實現的呢?答案就是代理物件。 代理又可以分為靜態代理和動態代理。 靜態代理:由程式設計師建立或特定工具自動生成原始碼,再對其編譯。在程式執行前,代理類的.class檔案就已經存在了。

spring aop原理 JDK動態代理CGLIB動態代理

lan ble -- 自定義 and ets spec gen ase Spring的兩大特性是IOC和AOPIOC負責將對象動態的註入到容器,從而達到一種需要誰就註入誰,什麽時候需要就什麽時候註入的效果。理解spring的ioc也很重要。但是今天主要來和大家講講aop。A

SpringAOP兩種代理機制對比(JDKCGLib動態代理

Sprign 動態代理機制 Spirng的AOP的動態代理實現機制有兩種,分別是: 1)JDK動態代理: 具體實現原理: 1、通過實現InvocationHandlet介面建立自己的呼叫處理器 2、

AOP之JDK動態代理CGLib動態代理

測試結果 edit print handle es2017 brush 類庫 構建 sets 一、JDK動態代理 JDK內置的Proxy動態代理可以在運行時動態生成字節碼,而沒必要針對每個類編寫代理類。中間主要使用到了一個接口InvocationHandler與Proxy

Spring的兩種代理方式:JDK動態代理CGLIB動態代理

轉自 :https://blog.csdn.net/cckevincyh/article/details/54962920   代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可譯為”代理“,所謂代理,就是一個人或者一個機構代表另一個人或者另一個機構採取行動。

Spring JDK動態代理CGLIB動態代理

的雙方各和進口量認同感和基你妹, 狂歡節空虛,嗎了 離開了是發;是否  進口量嗎, 的雙方各和進口量認同感和基你妹, 狂歡節空虛,嗎了 離開了是發;是否  進口量嗎, 的雙方各和進口量認同感和基你妹, 狂歡節空虛,嗎了 離開了是發;是否  進口量嗎, 

Spring 靜態代理+JDK動態代理CGLIB動態代理

代理分為兩種:靜態代理  動態代理 靜態代理:本質上會在硬碟上建立一個真正的物理類 動態代理:本質上是在記憶體中構建出一個類。 如果多個類需要進行方法增強,靜態代理則需要建立多個物理類,佔用磁碟空間。而動態代理則是在記憶體中建立,不會對磁碟進行影響。 靜態代理和JDK動態代理需要有介面。  CGLIB

JDK動態代理CGLIB動態代理,實現Spring註解管理事務區別。

註解式事務配置 1.JDK動態代理 <tx:annotation-driven transaction-manager="txManager"/>  預設啟用JDK動態代理,JDK只能代理介面不能代理類。 @Transactional註解可以標註在

由service層介面有什麼用?引申到基於JDK原生CGLIB動態代理實現spring事務管理的機制的思考

問題1:Services層為什麼要用(Services介面 類 + Services介面實現 類)分開,這樣做有什麼好處? 總結: 1.程式設計介面化, 2.Spring的事物管理預設用的是java動態代理。 問題2:Spring事物管理實現的機制

SSM(六)JDK動態代理Cglib動態代理

sys .com images 織入 load obj spa -1 instance 1.Cglib動態代理 目標類: 1 package cn.happy.proxy.cglib; 2 3 public class Service { 4 publ

03、動態代理--JDK動態代理CGLib動態代理的組合實例

listen -- offer pri eth err imp instance music package com.offer.note.Java基礎.動態代理.CGLib引入增強; public interface Browser { void visitI

jdk動態代理cglib動態代理

java動態代理 分享 運行 相同 ref 面向 () JD 回調方法 參考: http://www.importnew.com/22015.html Java動態代理 上面的代碼運行的結果為: I‘m proxy! Welcome oschina hosee‘s blo

Java核心-反射動態代理(JDK ProxyCglib

反射和動態代理放有一定的相關性,但單純的說動態代理是由反射機制實現的,其實是不夠全面不準確的,動態代理是一種功能行為,而它的實現方法有很多。要怎麼理解以上這句話,請看下文。 一、反射 反射機制是 Java 語言提供的一種基礎功能,賦予程式在執行時 自省 (intro

JDK動態代理CGLib動態代理區別

一、概括來說   JDK動態代理只能對實現了介面的類生成代理,而不能針對類   CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法(繼承) 二、Spring在選擇用JDK還是CGLiB的依據:    (1)當Bean實現介面時,Spring就

Java提高班(六)反射動態代理(JDK ProxyCglib

反射和動態代理放有一定的相關性,但單純的說動態代理是由反射機制實現的,其實是不夠全面不準確的,動態代理是一種功能行為,而它的實現方法有很多。要怎麼理解以上這句話,請看下文。 一、反射 反射機制是 Java 語言提供的一種基礎功能,賦予程式在執行時自省(introspect,官方用語)的能力。通過反射我們可