動態(tài)代理的實(shí)現(xiàn)
使用的模式:代理模式。
代理模式的作用是:為其他對象提供一種代理以控制對這個對象的訪問。類似租房的中介。
兩種動態(tài)代理:
(1)jdk動態(tài)代理,jdk動態(tài)代理是由Java內(nèi)部的反射機(jī)制來實(shí)現(xiàn)的,目標(biāo)類基于統(tǒng)一的接口(InvocationHandler)
(2)cglib動態(tài)代理,cglib動態(tài)代理底層則是借助asm來實(shí)現(xiàn)的,cglib這種第三方類庫實(shí)現(xiàn)的動態(tài)代理應(yīng)用更加廣泛,且在效率上更有優(yōu)勢。
主要應(yīng)用的框架:
Spring中的AOP,Struts2中的攔截器
具體實(shí)現(xiàn):
1、定義接口和實(shí)現(xiàn)類
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動態(tài)代理實(shí)現(xiàn)
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彌補(bǔ)了這一缺陷) } @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)); }}運(yùn)行結(jié)果:
------before getName------
------getName------
------after getName------
cat
------getAge------
10
3、cglib動態(tài)代理實(shí)現(xiàn):
JDK的動態(tài)代理機(jī)制只能代理實(shí)現(xiàn)了接口的類,而不能實(shí)現(xiàn)接口的類就不能實(shí)現(xiàn)JDK的動態(tài)代理,cglib是針對類來實(shí)現(xiàn)代理的,他的原理是對指定的目標(biāo)類生成一個子類,并覆蓋其中方法實(shí)現(xiàn)增強(qiáng),但因?yàn)椴捎玫氖抢^承,所以不能對final修飾的類進(jìn)行代理。
CGLIB的核心類:
net.sf.cglib.proxy.Enhancer 主站蜘蛛池模板: 波密县| 黔江区| 阿拉善盟| 舒城县| 女性| 东乡| 读书| 宁远县| 廊坊市| 大城县| 治多县| 东方市| 临洮县| 雷山县| 抚宁县| 凌云县| 安多县| 高密市| 民县| 湘西| 大姚县| 高安市| 逊克县| 化州市| 道真| 平湖市| 萝北县| 彭阳县| 尖扎县| 射洪县| 灵川县| 古浪县| 廊坊市| 修文县| 朔州市| 沽源县| 敦煌市| 东阿县| 余庆县| 松潘县| 余姚市|