动态代理模式
引言
用的最广泛的设计模式
定义
在实现阶段不用关心代理的是那个,在运行阶段才指定具体的代理。
实现原理
动态代理技术中的代理能够做比静态代理技术中的代理更多,更广的事。动态代理能够根据被代理类提供的操作动态生成相对应的操作而替代被代理类实现。
可以这样比喻,动态代理就是一个集代购电子产品,服装,化妆品,食品等业务于一身的综合代购,被代理者(用户)不管你想进行那类操作,代购都能对应的帮你完成。
动态代理是jdk的技术,使用java.lang.reflect包下提供的Proxy类和InvacationHandler接口,可以生成一个动态代理类和代理对象。
InvacationHandler接口需要被实现而重写invoke(target,method,args)方法,将被代理者需要进行的操作(通过method.invoke()方法获取相对应操作)和代购需要进行的操作合并,形成代理需要进行的操作。 Proxy类则将被代理者的对象类加载器,被代理者实现的接口以及代理需要进行的操作三者进行合并,用代理者对象类加载器和其实现的接口作为模板,生成相对应的代理类(有共同的接口和相似的类结构),将代理需要进行的操作合并到代理类中,形成新生成的代理类的具体操作。
实现步骤
第一步,创建实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| package com.test.bean;
public class User { private int id ; private String name ; private int age ; private String sex ;
public User() { }
public User(int id, String name, int age, String sex) { this.id = id; this.name = name; this.age = age; this.sex = sex; }
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }
@Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", sex='" + sex + '\'' + '}'; } }
|
第二步,创建事务类
1 2 3 4 5 6 7 8 9 10 11 12
| package com.test.transaction;
public class MyTransaction { public void before(){ System.out.println("打开事务"); }
public void after(){ System.out.println("关闭事务"); } }
|
第三步,创建共同接口
1 2 3 4 5 6 7 8 9 10 11 12
| package com.test.service;
import com.test.bean.User;
public interface UserService { public void addUser(User u); public void delete(int id); }
|
第四步,创建被代理者的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.test.serviceImpl;
import com.test.bean.User; import com.test.service.UserService;
public class UserServiceImpl implements UserService { public void addUser(User u) { System.out.println("增加用户"); }
public void delete(int id) { System.out.println("删除用户"); } }
|
第五步,创建动态代理的抽象操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| package com.test.serviceImpl;
import com.test.transaction.MyTransaction;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;
public class ObjectIntercepter implements InvocationHandler { private Object target ; private MyTransaction myTransaction ;
public ObjectIntercepter() { }
public ObjectIntercepter(Object target, MyTransaction myTransaction) { this.target = target; this.myTransaction = myTransaction; }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { this.myTransaction.before(); method.invoke(this.target , args); this.myTransaction.after(); return null; } }
|
第六步,测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import com.test.bean.User; import com.test.service.UserService; import com.test.serviceImpl.ObjectIntercepter; import com.test.serviceImpl.UserServiceImpl; import com.test.transaction.MyTransaction; import org.junit.Test;
import java.lang.reflect.Proxy;
public class test { UserService us = new UserServiceImpl(); MyTransaction mt = new MyTransaction(); ObjectIntercepter oi = new ObjectIntercepter(us,mt);
@Test public void test(){ UserService userService = (UserService)Proxy.newProxyInstance(us.getClass().getClassLoader(), us.getClass().getInterfaces(), oi); userService.delete(1); } }
|
总结
动态代理技术就相当于一个自动化工厂,将一个个不同型号的零部件适配组装成不同类型的产品。
理解动态代理,可以与静态代理相结合。动态代理的出现就是解决静态代理的缺陷。知道动态代理的功能后,顺藤摸瓜,就能知道动态代理的实现原理。
自然言语
忙了几天,终于抽出时间把动态代理这块给理清了。加上这个已经理清两个设计模式,有朝一日我要把java的23种设计模式都弄出来。
剩余:21种。