代理模式就是新增加一个代理类,然后通过代理类来调用我们的实现。
应用场景可以参考中介。
1.未使用代理类场景
未使用代理类,即接口直接通过实现类实现功能
接口:
public interface UserDao {
public void updateUser();
public void delUser();
}
实现类:
public class UserDaoImpl implements UserDao{
@Override
public void updateUser() {
System.out.println("更新用户成功");
}
@Override
public void delUser() {
System.out.println("删除用户成功");
}
}
测试类:
public class Test {
public static void main(String[] args) {
UserDao userDao=new UserDaoImpl();
userDao.delUser();
userDao.updateUser();
}
}
2.使用代理类
2.1静态代理类
即新增一个代理类,来管理我们的实现类,我们可以在代理类中添加一些动作
将具体的实现通过构造器注入,然后代理类中调用我们对应的实现类的方法,
新增的代理类如下:
public class StaticProxy implements UserDao{
private UserDao userDao;
public StaticProxy(UserDao userDao1)
{
this.userDao=userDao1;
}
@Override
public void updateUser() {
System.out.println("begin");
userDao.updateUser();
System.out.println("end ");
}
@Override
public void delUser() {
System.out.println("begin");
userDao.delUser();
System.out.println("end");
}
}
测试类
public class ProxyTest {
public static void main(String[] args) {
UserDao userDaoProxy=new StaticProxy(new UserDaoImpl());
userDaoProxy.delUser();
userDaoProxy.updateUser();
}
}
结果如下
2.2由静态代理类引出动态代理类
-
可以看见,我们的静态代理类也实现了UserDao接口,当接口新增内容时,如新增一个query()方法,此时,我们的UserDaoImpl和StaticProxy类都要改变。-
-
这是我们不想看见的,我们希望代理类可以不做修改,只需要修改我们的实现类的内容。由此引出了动态代理类(由此动态代理类的作用也显而易见)
2.3动态代理类
定义动态代理工具类
返回指定的接口,将方法调用指定的调用处理程序的代理类的一个实例
三个参数可以查阅JDK明细,主要需要实现InvocationHandler
接口,实现invoke
方法,通过反射实现对抽象接口方法的调用method.invoke(target, args),
调其中target就是我们真正的实现类
-------------------------------------
public class DynamicProxy {
public static void main(String[] args) {
UserDao userDao = (UserDao) Proxy.newProxyInstance(
UserDao.class.getClassLoader(),
new Class[]{UserDao.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("proxy begin");
Object result = method.invoke(new UserDaoImpl(), args);
System.out.println("proxy end");
return result;
}
}
);
userDao.delUser();
},
3.总结
-
核心在于ProxyGenerator.generateProxyClass,返回的byte[]为对象字节数组,生成代理对象。
-
代理模式强调一些通用功能的扩展,在方法执行前,执行后添加点什么东西(LOG),静态即单一的扩展,动态为多个类扩展,但是都引入新的代理类,从性能上讲,新的代理类会导致性能有所下降.