1. 程式人生 > >Spring07-aop動態代理

Spring07-aop動態代理

 動態代理:

         *    作用:不改變原始碼的基礎上,對已有方法增強。(它是AOP思想的實現技術)          *    分類:                     1.基於介面的動態代理

                    2.基於子類的動態代理

      需要加入的包:

                   

一.基於介面的動態代理

            要求:被代理類最少實現一個介面          *                提供者:JDK官方          *                涉及的類:Proxy          *         建立代理物件的方法:newProxyInstance(ClassLoader(), Class[], InvocationHandler)          *              引數的含義:          *                    ClassLoader:類載入器。和被代理物件使用相同的類載入器。一般都是固定寫法。(類名.getClass().getClassLoader())          *                    Class[]:位元組碼陣列。被代理類實現的介面。(要求代理物件和被代理物件具有相同的行為)。一般是固定寫法(類名.getClass().getInterfaces())          *                    InvocationHandler:它是一個介面,就是用於我們提供增強程式碼的。我們一般都是些一個該介面的實現類。實現類可以是匿名內部類。          *                                      它的含義就是:如何代理。此處的程式碼只能是誰用誰提供。          *                                      策略模式:          *                                          使用要求:資料已經有了          *                                                 目的明確          *                                                 達到目標的過程就是策略。          *                                          在dbutils中的ResultSetHandler就是策略模式的具體應用

       使用invoke方法:public Object invoke(Object proxy, Method method, Object[] args)

        執行被代理物件的任何方法都會經過該方法,該方法有攔截的功能             * 方法的引數             *     Object proxy:代理物件的引入。不一定每次都會有。             *     Method method:當前執行的方法。             *     Object[] args:當前執行方法所需的引數             * 返回值:             *     當前執行方法的返回值

package com.lixin.proxy;

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

/*
 * 模擬一個劇組
 */

public class Client {

	public static void main(String[] args) {
	    final Actor actor=new Actor();
	   	   IActor proxyActor= (IActor) Proxy.newProxyInstance(actor.getClass().getClassLoader(), actor.getClass().getInterfaces(), new InvocationHandler() {
			
		   
		   
		  			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				Object rtValue=null;
				//1.取出執行方法中的引數:給的多少錢
				Float money=(Float)args[0];
				//2.判斷當前執行的是什麼方法
				if("basicAct".equals(method.getName())) {
					 if(money>10000) {
						 //執行方法,開始表演
						 rtValue=method.invoke(actor, money/2);
					 }
				}
				if("dangerAct".equals(method.getName())) {
					if(money>50000) {
						//執行方法,開始表演
						rtValue=method.invoke(actor, money/2);
					}
				}
				return rtValue;
			}
		});
	   proxyActor.basicAct(20000);
	   proxyActor.dangerAct(60000);
	}

}

二.基於子類的動態代理

 要求:被代理類不能是最終類。不能被final修飾          *                 提供者:第三方CGLib          *                 涉及的類:Enhancer          *                 建立代理物件的方法:create(Class,Callback);          *                 引數的含義:          *                      Class:被代理物件的位元組碼          *                      Callback:如何代理。它和InvocationHandler的作用是一樣的。它也是一個介面,我們一般使用該介面的子介面MethodInterceptor          *                               在使用時我們也是建立介面的匿名內部類。

      intercept方法:public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)

執行被代理物件的任何方法,都會經過該方法。它是基於介面動態代理和invoke方法的作用是一模一樣的。              * 方法的引數:              *    前面三個和invoke方法的引數含義和作用都一樣。              *    MethodProxy methodProxy:當前執行方法的代理物件。一般不用

package com.lixin.cglib;

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

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

/*
 * 模擬一個劇組
 */

public class Client {

	public static void main(String[] args) {
	    final Actor actor=new Actor();
	    Actor cglibActor=(Actor) Enhancer.create(actor.getClass(), new MethodInterceptor() {
	 			@Override
			public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
				Object rtValue=null;
				//1.取出執行方法中的引數:給的多少錢
				Float money=(Float)args[0];
				//2.判斷當前執行的是什麼方法
				if("basicAct".equals(method.getName())) {
					 if(money>10000) {
						 //執行方法,開始表演
						 rtValue=method.invoke(actor, money/2);
					 }
				}
				if("dangerAct".equals(method.getName())) {
					if(money>50000) {
						//執行方法,開始表演
						rtValue=method.invoke(actor, money/2);
					}
				}
				return rtValue;
			}
		});
	    cglibActor.basicAct(50000);
	    cglibActor.dangerAct(100000);
	     
	}

}