动态代理

JDK动态代理必须要有接口,且JDK提供的代理只能针对接口做代理。
Spring 框架,使用代理模式对目标对象中的功能进行增强
动态代理设计模式:可以在不修改源代码的清空下,对功能做出增强。
代理对象是在运行期间,通过反射生成的。
Proxy 代理类可以生成代理对象。

  1. 首先是创建接口类对象;
接口类:
public interface UserDao {
    void insert();
    void update();
}
接口实现类:现在就是想实现类中的功能进行增强;
传统的方法需要在此部分直接操作,不易于维护和开发,利用动态代理更易于实现;
public class UserDaoImpl implements UserDao {
    @Override
    public void insert() {
        System.out.println("添加用户");
    }

    @Override
    public void update() {
        System.out.println("修改用户");
    }
}
  1. 创建动态代理类,使用目标实现类作为参数,进而进行增强和更新;
    在使用代理类调用:
    newProxyInstance (ClassLoader loader, Class < ?>[]interfaces, InvocationHandler h),
    这个方法的时候需要传入:

参数1. *ClassLoader:类加载器:它是用于加载代理对象字节码的,和被代理对象使用相同的类加载器,是固定写法。
参数2:Class[]:字节码数组:它是用于让代理对象和被代理对象有相同方法。固定写法。
参数3:InvocationHandler:用于提供增强的代码,它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。此接口的实现类都是谁用谁写。

public class ProxyUtils {

public static UserDao getProxy(UserDao dao) { //传入过来的目标对象
UserDao obj= (UserDao) Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), new InvocationHandler() {


重写的方法中,若判断为两者中的某一个,即对此方法增强;
方法参数同时也需要 
proxy:代理对象的引用
method:当前执行的方法,也就是需要增强目标实现类中的方法;
args :当前执行方法所需的参数
return :和被代理对象方法有相同的返回值,即返回增强后的方法对象;        
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              
  		Object invoke=null;
		if(method.getName().equals("insert")||method.getName().equals("update")){
      		 System.out.println("权限校验");
       		 invoke = method.invoke(dao); //调用目标对象中的方法
             System.out.println("记录日志");
		 }
		return invoke;
   }
});
创建对象后,返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
        return obj;
    }
}

测试类:
		1. 创建接口类对象实例
 		UserDao dao = new UserDaoImpl();
        2. 获取代理对象:调用静态类获取一个代理类实例对象;
        UserDao proxy = ProxyUtils.getProxy(dao);
        3. 使用代理类对象调用目标增强方法;
        proxy.insert();
        proxy.update();
        
        从而实现对目标对象的功能进行增强,如下图:

动态代理_第1张图片

你可能感兴趣的:(JAVA)