java之代理设计模式
代理模式是常用的java設(shè)計(jì)模式,他的特征是代理類與委托類有同樣的接口,代理類主要負(fù)責(zé)為委托類預(yù)處理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等。代理類與委托類之間通常會(huì)存在關(guān)聯(lián)關(guān)系,一個(gè)代理類的對(duì)象與一個(gè)委托類的對(duì)象關(guān)聯(lián),代理類的對(duì)象本身并不真正實(shí)現(xiàn)服務(wù),而是通過調(diào)用委托類的對(duì)象的相關(guān)方法,來提供特定的服務(wù)。
按照代理的創(chuàng)建時(shí)期,代理類可以分為兩種。
靜態(tài)代理:由程序員創(chuàng)建或特定工具自動(dòng)生成源代碼,再對(duì)其編譯。在程序運(yùn)行前,代理類的.class文件就已經(jīng)存在了。
動(dòng)態(tài)代理:在程序運(yùn)行時(shí),運(yùn)用反射機(jī)制動(dòng)態(tài)創(chuàng)建而成。
靜態(tài)代理
2、 目標(biāo)類
package cn.itcast.proxy.sh;public class PersonDaoImpl implements PersonDao{public void deletePerson() {System.out.println("delete person");}public void savePerson() {System.out.println("save person");}public void updatePerson() {System.out.println("update person");} }3、代理類,包含了目標(biāo)類和一些額外的操作
package cn.itcast.proxy.sh;public class PersonDaoProxy implements PersonDao{private PersonDao personDao;private Transaction transaction;public PersonDaoProxy(PersonDao personDao,Transaction transactions){this.personDao = personDao;this.transaction = transactions;}public void deletePerson() {this.transaction.beginTransaction();this.personDao.deletePerson();this.transaction.commit();}public void savePerson() {this.transaction.beginTransaction();this.personDao.savePerson();this.transaction.commit();}public void updatePerson() {this.transaction.beginTransaction();this.personDao.updatePerson();this.transaction.commit();} }4、使用
package cn.itcast.proxy.sh;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class ProxyTest {@Testpublic void test(){ApplicationContext context = new ClassPathXmlApplicationContext("cn/itcast/proxy/sh/applicationContext-proxy.xml");PersonDao personDao = (PersonDao)context.getBean("personDao2");personDao.deletePerson();} }靜態(tài)代理的缺點(diǎn)
靜態(tài)代理模式的缺點(diǎn):
1、如果一個(gè)系統(tǒng)中有100Dao,則創(chuàng)建100個(gè)代理對(duì)象
2、如果一個(gè)dao中有很多方法需要事務(wù),則代理對(duì)象的方法中重復(fù)代碼還是很多
3、由第一點(diǎn)和第二點(diǎn)可以得出:proxy的重用性不強(qiáng)
動(dòng)態(tài)代理
1、產(chǎn)生的代理對(duì)象和目標(biāo)對(duì)象實(shí)現(xiàn)了共同的接口
jdk動(dòng)態(tài)代理
2、代理對(duì)象是目標(biāo)對(duì)象的子類
hibernate: Person person = session.load(Person.class,1L); javassisit
spring:cglib動(dòng)態(tài)代理
jdk的動(dòng)態(tài)代理:
1、因?yàn)槭怯胘dk的API做到的
2、代理對(duì)象是動(dòng)態(tài)產(chǎn)生的
cglib產(chǎn)生的代理類是目標(biāo)類的子類
注意事項(xiàng):
1、攔截器中invoke方法體的內(nèi)容就是代理對(duì)象方法體的內(nèi)容
2、當(dāng)客戶端執(zhí)行代理對(duì)象.方法時(shí),進(jìn)入到了攔截器的invoke方法體
3、攔截器中invoke方法的method參數(shù)是在調(diào)用的時(shí)候賦值的
jdk動(dòng)態(tài)代理
定義一個(gè)接口
package cn.itcast.jdkproxy.sh;public interface PersonDao {public void savePerson();public void updatePerson();public void deletePerson(); }目標(biāo)類
package cn.itcast.jdkproxy.sh;public class PersonDaoImpl implements PersonDao{public void deletePerson() {System.out.println("delete person");}public void savePerson() {System.out.println("save person");}public void updatePerson() {System.out.println("update person");} }攔截器
package cn.itcast.jdkproxy.sh;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;/*** 攔截器* @author Think* 1、引入目標(biāo)類* 2、引入事務(wù)* 3、通過構(gòu)造函數(shù)給目標(biāo)類和事務(wù)賦值* 4、填充invoke方法**/ public class PersonInterceptor implements InvocationHandler{private Object target;//目標(biāo)類private Transaction transaction;//引入事務(wù)public PersonInterceptor(Object target,Transaction transaction){this.target = target;this.transaction = transaction;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubthis.transaction.beginTransaction();method.invoke(this.target, args);//調(diào)用目標(biāo)類的方法this.transaction.commit();return null;}}使用
package cn.itcast.jdkproxy.sh;import java.lang.reflect.Proxy;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class ProxyTest {@Testpublic void test(){Object target = new PersonDaoImpl();Transaction transaction = new Transaction();PersonInterceptor interceptor = new PersonInterceptor(target, transaction);/*** 1、目標(biāo)類的類加載器* 2、目標(biāo)類實(shí)現(xiàn)的所有的接口* 3、攔截器*/PersonDao personDao = (PersonDao)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);personDao.deletePerson();} }cglib動(dòng)態(tài)代理
JDK的動(dòng)態(tài)代理機(jī)制只能代理實(shí)現(xiàn)了接口的類,而不能實(shí)現(xiàn)接口的類就不能實(shí)現(xiàn)JDK的動(dòng)態(tài)代理,cglib是針對(duì)類來實(shí)現(xiàn)代理的,他的原理是對(duì)指定的目標(biāo)類生成一個(gè)子類,并覆蓋其中方法實(shí)現(xiàn)增強(qiáng),但因?yàn)椴捎玫氖抢^承,所以不能對(duì)final修飾的類進(jìn)行代理。
目標(biāo)類
package net.battier.dao.impl; /** * 這個(gè)是沒有實(shí)現(xiàn)接口的實(shí)現(xiàn)類 * * @author student * */ public class BookFacadeImpl1 { public void addBook() { System.out.println("增加圖書的普通方法..."); } }攔截類
package net.battier.proxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 使用cglib動(dòng)態(tài)代理 * * @author student * */ public class BookFacadeCglib implements MethodInterceptor { private Object target; /** * 創(chuàng)建代理對(duì)象 * * @param target * @return */ public Object getInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // 回調(diào)方法 enhancer.setCallback(this); // 創(chuàng)建代理對(duì)象 return enhancer.create(); } @Override // 回調(diào)方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("事物開始"); proxy.invokeSuper(obj, args); System.out.println("事物結(jié)束"); return null; } }使用
package net.battier.test; import net.battier.dao.impl.BookFacadeImpl1; import net.battier.proxy.BookFacadeCglib; public class TestCglib { public static void main(String[] args) { BookFacadeCglib cglib=new BookFacadeCglib(); BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1()); bookCglib.addBook(); } }參考鏈接
java動(dòng)態(tài)代理(JDK和cglib) - C’est la vie - 博客園
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的java之代理设计模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 认识蚁群算法
- 下一篇: 设计模式3—行为型模式