1.什么是代理
有一些场景下,个人不想完成一些事情,所以需要一个人来帮助完成这件事。比如房产中介。
代理有什么用?有一些场景,个人并不是很想干这种事。
-
比如买东西,去日本买,对于个人来说,我只想要一个东西,并不想去日本,可以找一个代理的中介帮助我们处理这个。
-
比如打官司,对于前期的收集材料,后期的一些补充材料
2.代理分类
代理有两种实现方式:静态代理,动态代理。
它们的主要区别,静态代理会自己实现类,动态代理,则是运行时,JVM给你动态生成类,这是两者之间的主要区别。
2.1静态代理
静态代理,是自己手动实现前置接口,然后写死功能,这就是静态代理
/**
* 租房接口
*
* @author Common-zhou
* @since 2023-08-28 14:30
*/
public interface IRentHouse {
/**
* 租房接口,传入钱,返回是否租到
*
* @param money 钱
* @return 是否租到
*/
boolean rent(Integer money);
}
public class RealRenter implements IRentHouse {
@Override
public boolean rent(Integer money) {
System.out.println("出" + money + "租房。。。");
return true;
}
}
public class RentHouseProxy implements IRentHouse {
private IRentHouse iRentHouse;
public RentHouseProxy(IRentHouse iRentHouse) {
this.iRentHouse = iRentHouse;
}
@Override
public boolean rent(Integer money) {
System.out.println("前置的房源寻找ing......");
System.out.println("沟通中......");
boolean rent = iRentHouse.rent(money);
System.out.println("后置的合同草拟,沟通......");
return rent;
}
}
2.2动态代理
在Java中的动态代理,需要使用以下步骤:
- 接口
- 自定义实现类
- 动态代理需要完成的功能,需要实现一个接口
- 使用Proxy.newInstance方法完成初始化,在运行时动态生成实现类。
public interface IRentHouse {
/**
* 租房接口,传入钱,返回是否租到
*
* @param money 钱
* @return 是否租到
*/
boolean rent(Integer money);
}
public class RealRenter implements IRentHouse {
@Override
public boolean rent(Integer money) {
System.out.println("出" + money + "租房。。。");
return true;
}
}
public class RentHouseProxy implements IRentHouse {
private IRentHouse iRentHouse;
public RentHouseProxy(IRentHouse iRentHouse) {
this.iRentHouse = iRentHouse;
}
@Override
public boolean rent(Integer money) {
System.out.println("前置的房源寻找ing......");
System.out.println("沟通中......");
boolean rent = iRentHouse.rent(money);
System.out.println("后置的合同草拟,沟通......");
return rent;
}
}
一般真实的业务场景,比如缓存,比如日志。不可能在每一个实现类都去写这种代码,非常的麻烦,所以需要使用这种动态代理。
Proxy.newProxyInstance
是 Java 提供的用于创建动态代理对象的静态方法。它接受三个参数,详细介绍一下这些参数,以及一般传入什么值。
javaCopy codepublic static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
- ClassLoader (
loader
): 这是一个用于加载代理类的ClassLoader
。代理类是在运行时生成的,所以需要一个类加载器来加载它。通常情况下,你可以使用被代理类的ClassLoader
,也就是实现被代理接口的类的类加载器。例如,如果被代理的接口是UserService
,那么一般会传入UserService.class.getClassLoader()
。 - Class<?>[] (
interfaces
): 这是一个数组,包含了代理类要实现的接口列表。动态代理对象需要实现一个或多个接口,因此你需要传入被代理接口的类类型。例如,如果你的被代理接口是UserService
,则传入new Class<?>[] { UserService.class }
。 - InvocationHandler (
h
): 这是一个实现了InvocationHandler
接口的对象,用于处理代理对象上的方法调用。InvocationHandler
接口中的invoke
方法会在代理对象的方法调用时被触发,你可以在这个方法中实现你的逻辑。通常情况下,你会创建一个类,实现InvocationHandler
接口,将实际对象传递给它,然后在invoke
方法中添加你想要的处理逻辑。
综上所述,一般来说,你会将被代理接口的 ClassLoader
、被代理接口的类类型数组,以及实现了 InvocationHandler
接口的处理器对象作为参数传递给 Proxy.newProxyInstance
方法。这样,当代理对象的方法被调用时,会触发处理器中的逻辑。