动态代理还是了解的比较有限…

静态代理
静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同的父类
静态代理的局限性:只能代理某一类型接口的实例,不能做到任意接口任意方法的操作,同时如果需要代理多个类的时候,每个委托类都要编写一个代理类,会导致代理类繁多,不好管理。。
代理步骤:
1、定义一个接口,所有需要委托(被代理)类都实现该接口
//Mapper.java
package Proxy.StaticProxy;
public interface Mapper {
public void jdbcOpera();
}
2、定义一个委托(被代理)类,在jdbcOpera()
方法中编写业务代码
//UserMapper.java
package Proxy.StaticProxy;
public class UserMapper implements Mapper{
public void jdbcOpera(){
System.out.println("===========执行User核心业务代码==");
}
}
3、定义一个代理类,其中再调用被代理类的方法
package Proxy.StaticProxy;
public class StaticProxy {
public void startJdbcOpera(Mapper mapper){ //接口作为参数
System.out.println("开始代理");
//调用被代理对象的业务处理
mapper.jdbcOpera();
System.out.println("代理结束");
}
}
4、定义一个测试类
package Proxy.StaticProxy;
public class Test {
public static void main(String[] args) {
//创建被代理对象
UserMapper userMapper = new UserMapper();
//创建代理对象
StaticProxy sp = new StaticProxy();
//代理对象开始代理
sp.startJdbcOpera(userMapper);
}
}
JDK动态代理
JDK动态代理灵活性很大,在任意时候任意地方都可以使用任意功能,前提是该对象有接口
一些重要的方法:
-
java.lang.reflect.Proxy
:这是Java动态代理机制的主类,他提供了一组静态方法来为一组接口动态地生成代理类及其对象。 -
Proxy
类的newProxyInstance
方法用于动态生成代理对象
public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
}
-
java.lang.reflect.InvocationHandler
:这是进行实际业务增强处理的类,他自定义类一个invoke方法,通常在该方法中实现对委托类的代理访问。InvocationHandler
的核心方法invoke方法,该方法负责集中处理动态代理类上的所有方法调用。public Object invoke(Object o, Method method, Object[] args) 第一个参数:动态代理类实例;第二个参数:被调用的方法对应的Method对象;第三个参数:被调用的方法中声明的参数
代理步骤:
1)创建自定义调用处理器
1.1、创建自定义调用处理器并实现java.lang.InvocationHandler
接口,由它来实现invoke
方法,执行代理函数。
1.2、定义一个方法获取动态生成代理对象,其中调用Proxy.newProxyInstance
:分别传入类加载器,被代理接口,调用处理器;
1.3、通过重写InvocationHandler
接口中唯一的invoke
方法进行业务增强处理
package Proxy.Dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 实现InvocationHandle接口
* InvocationHandler接口中声明了一个invoke方法,invoke方法是实际进行业务增强处理
*/
public class MyHandler implements InvocationHandler {
//声明被代理对象,目标
private Object target;
public MyHandler(){
}
public MyHandler(Object target){
this.target = target;
}
//定义方法,获取动态生成代理对象
public Object getProxyInstance(){
//通过Proxy类的newProxyInstance方法,动态生成“中介”
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
/**
*
* @param o 动态生成的代理对象的实例
* @param method 被代理对象当前正在执行的业务方法
* @param args 被代理对象当前正在执行的业务方法中的参数
* @return
* @throws Throwable
*/
//通过invoke方法进行业务增强处理
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
System.out.println("===========获取数据库连接===");
method.invoke(target,args);
System.out.println("=========关闭连接=======");
return null;
}
}
2)定义接口
//UMapper.java
package Proxy.Dynamic;
public interface UMapper {
public void jdbcOpera();
}
3)定义被代理类,其实现上述接口,并写下业务代码
//UserMapper.java
package Proxy.Dynamic;
public class UserMapper implements UMapper {
public void jdbcOpera(){
System.out.println("===========执行User核心业务代码==");
}
}
4)测试类
//Test.java
package Proxy.Dynamic;
public class Test {
public static void main(String[] args) {
//创建代理对象
UserMapper userMapper = new UserMapper();
MyHandler myHandler = new MyHandler(userMapper);
//获取动态代理
UMapper mi = (UMapper) myHandler.getProxyInstance();
mi.jdbcOpera();
}
}
参考:
https://xz.aliyun.com/t/9197
https://www.bilibili.com/video/BV1N4411672a