描述:代理对象和被代理对象具有相同的行为,客户端通过代理对象实现对被代理对象调用,代理对象除了可以代理被代理对象的所有行为外,还可以在被代理对象的所有行为上添加一些额外的内容,如开闭事务,权限拦截等;动态代理可以生成一个不用实现被代理类的所有接口的代理类,它内部通过被代理类的classLoader和反射机制实现被代理类的所有接口。。
场景:在数据库操作中,假如所有增删改查操作都需要加log记录,可以代理这个数据库操作,然后在运行这些增删改查操作时加一个log记录,客户端使用方式仍然不变。
实现:
数据库操作:
interface Dao {
void insert();
void delete();
}
关于人员的数据库操作:
class UserDao implements Dao {
@Override
public void insert() {
System.out.println("insert user instance to db!");
}
@Override
public void delete() {
System.out.println("delete user instance from db!");
}
}
定义一个代理类代理UserDao,如果使用静态代理,那么这个类必须实现Dao接口,这里采用动态代理类,免去实现代理类定义的所有接口。
class UserDaoProxy implements InvocationHandler {
Dao dao;
UserDaoProxy(Dao dao) {
this.dao = dao;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(dao, args);
after();
return result;
}
private void before() {
System.out.println("开始log...");
}
private void after() {
System.out.println("结束log");
}
}
客户端调用:
public class ProxyDemo {
public static void main(String[] args) {
UserDaoProxy proxy = new UserDaoProxy(new UserDao());
Dao dao = (Dao)Proxy.newProxyInstance(UserDao.class.getClassLoader(), UserDao.class.getInterfaces(), proxy);
dao.insert();
dao.delete();
}
}
打印结果:
开始log...
insert user instance to db!
结束log
开始log...
delete user instance from db!
结束log
结论:通过代理类即能保持原接口调用不变,还能对接口调用的前后增加额外的业务代码,甚至可以改变接口的实现,why?想想现实中的代理就知道了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。