代理模式(静态代理和动态代理)
代理模式:我觉得就是类似于Spring AOP,在不改变原有类的情况下,给某个方法的调用加一些条件。
一、静态代理(租房子):
gerry需要租房子,中介帮他找房子,双方都得实现一个协议-IRent接口
中介类中找到需要租房子的人,IRent rent;通过构造函数把传进来的租房人给rent,再用rent调用方法
1 package deep.staticc.demo;2 3 public interface IRent {4 5 public void rentHouse(String name);6 }
1 package deep.staticc.demo; 2 3 4 5 /** 6 * 场景:gerry工作非常忙,没有时间找房子,需要找一个中介帮忙 7 * @author DeepSleeping 8 * 9 */10 public class Gerry implements IRent{11 12 @Override13 public void rentHouse(String name){14 System.out.println(name + "需要租房子");15 }16 }
1 package deep.staticc.demo; 2 3 public class Medium implements IRent { 4 5 //持有目标代理类的引用 6 private IRent rent; 7 8 public Medium(IRent rent){ 9 this.rent = rent;10 }11 12 13 @Override14 public void rentHouse(String name) {15 rent.rentHouse(name);16 }17 18 }
1 package deep.staticc.demo; 2 3 public class TestProxy { 4 public static void main(String[] args) { 5 //创建目标对象 6 IRent target = new Gerry(); 7 //创建一个代理对象 8 IRent proxy = new Medium(target); 9 //通过代理调用方法10 proxy.rentHouse("gerry");11 }12 }
静态代理总结:局限性太大,只有共同实现了某一个接口才能够代理,即都实现了IRent接口通过多态来运转。
二、动态代理(添加信息前进行权限认证)
1 package deep.dynamic.demo;2 3 public interface IUserDao {4 5 void add();6 7 void deletd();8 9 }
1 package deep.dynamic.demo; 2 3 /** 4 * 实现认证操作功能: 5 * 项目中每一个方法的调用都需要进行4个认证 6 * 1、是否合法 7 * 2、是否有新增权限 8 * 3、开启事务 9 * 4、关闭事务10 * @author DeepSleeping11 *12 */13 public class UserDaoImpl implements IUserDao {14 15 @Override16 public void add(){17 System.out.println("新增信息");18 }19 20 @Override21 public void deletd() {22 System.out.println("删除信息");23 24 }25 }
1 package deep.dynamic.demo.proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 7 /** 8 * 动态代理类 9 * @author DeepSleeping10 *11 */12 public class ProxyClass {13 //目标对象14 private Object target;15 16 public ProxyClass(Object target){17 this.target = target;18 }19 20 /**21 * 创建当前目标对象代理对象22 * @return23 */24 public Object createProxy(){25 /**26 * loader:目标对象的类加载器27 * interfaces:目标对象实现的所有接口组成的数组28 * handler:定义一个调用目标类中方法的回调类29 */30 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),31 new InvocationHandler() {32 33 @Override34 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {35 //进行调用前的认证36 System.out.println("1、是否合法");37 System.out.println("2、是否有权限"); 38 System.out.println("3、开启事务");39 Object obj = null;40 41 42 try {43 method.invoke(target, args);44 45 } catch (Exception e) {46 System.out.println("4、关闭事务");47 } 48 System.out.println("--业务执行正常--");49 50 return obj;51 }52 });53 }54 }
1 package deep.dynamic.demo; 2 3 import deep.dynamic.demo.proxy.ProxyClass; 4 5 public class TestDynamicProxy { 6 7 public static void main(String[] args) { 8 //创建目标对象 9 IUserDao target = new UserDaoImpl();10 //创建代理类的实例11 ProxyClass proxy = new ProxyClass(target);12 //生成对应的代理对象13 IUserDao userDao = (IUserDao) proxy.createProxy();14 userDao.add();15 userDao.deletd();16 }17 }
附加:为什么可以强转IUserDao userDao = (IUserDao) proxy.createProxy();
是因为Proxy.newProxyInstance方法的第二个参数取得了目标对象的所有实现的接口的数组,代理对象就会实现这组接口,所以我们就可以将代理对象任意强转成这组接口的任意一个。
静态代理:共同实现一个接口,通过多态调用
动态代理:动态地实现同一个接口(通过方法传目标对象实现过的接口,然后底层自动实现它们,这样就像静态代理那样,目标和代理对象都实现了同一个接口)然后又可以利用多态强转后调用
原文出处:http://www.cnblogs.com/deepSleeping/p/9381965.html