静态代理和动态代理
摘自百度AI:静态代理模式通过显式创建代理类实现,需手动定义代理类和被代理类,二者均需实现同一接口。
·
静态代理
- 抽象接口
- 目标类和代理类实现同一个抽象接口
- 在代理类中通过构造方法将目标类注入
- 通过操作代理类的方式 来实现对目标类业务的操作
/**
* 目标类和代理类都要实现抽象接口的抽象方法
*/
public interface StudentMapper {
public void delete();
}
/**
* 目标对象 实现抽象接口 执行删除
*/
public class StudentImpl implements StudentMapper {
@Override
public void delete() {
System.out.println("目标类删除");
}
}
/**
* 代理对象 实现抽象接口 执行删除
*/
public class StudentProxyImpl implements StudentMapper {
private StudentImpl studentImpl;
public StudentProxyImpl(StudentImpl studentImpl) {
this.studentImpl = studentImpl;
}
public void setStudentImpl(StudentImpl studentImpl) {
this.studentImpl = studentImpl;
}
public StudentProxyImpl() {
}
@Override
public void delete() {
studentImpl.delete();
}
}
public static void main(String[] args) {
StudentImpl student = new StudentImpl();
// 构造方法注入对象
StudentProxyImpl studentProxy1 = new StudentProxyImpl(student);
studentProxy1.delete();
// spring中建议用set方法注入对象
StudentProxyImpl studentProxy2 = new StudentProxyImpl();
studentProxy2.setStudentImpl(student);
studentProxy2.delete();
}
优点:
- 代理类可以继续去做别的操作,而目标类不会受到干扰。
缺点:
- 每新增一个目标类对应的就会多出一个代理类
- 共同实现的接口如果新增方法,那么代理类和目标类都要维护
JDK动态代理
Java语言中位于java.lang.reflect包下的编程机制,通InvocationHandler接口和Proxy类实现。
- 定义一个接口
- 目标类实现这个接口
- 编写一个动态代理类实现InvocationHandler接口,重写invoke()方法
- 引用目标类并通过set方法注入目标类
- 动态代理类的静态方法newInstance方法,通过反射机制创建一个新的接口实现类(代理类)https://blog.csdn.net/qq_34534731/article/details/150521441?spm=1011.2415.3001.5331
- 代理调用方法,达到目标类执行的效果
package com.cht.mapper;
public interface StudentMapper {
public abstract void delete();
}
public class StudentImpl implements StudentMapper {
@Override
public void delete() {
System.out.println("目标类删除");
}
}
public class DynamicsProxy implements InvocationHandler {
// 目标类
private StudentImpl studentImpl;
// 通过set方法注入目标类
public void setStudentImpl(StudentImpl studentImpl) {
this.studentImpl = studentImpl;
}
// 通过目标类的接口获取它的代理类,代理类其实就是接口的另一个实现类,只是通过动态代理反向获取。
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), studentImpl.getClass().getInterfaces(), this);
}
// 通过反射机制,拦截代理类的方法调用。并可以添加自己的其它功能
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("日志开始");
// 拦截代理类的方法调用
Object invoke = method.invoke(studentImpl, args);
System.out.println("日志结束");
return invoke;
}
}
public static void main(String[] args) {
// 目标类
StudentImpl studentImpl = new StudentImpl();
// 动态代理注入目标类
DynamicsProxy dynamicsProxy = new DynamicsProxy();
dynamicsProxy.setStudentImpl(studentImpl);
// 通过目标类获取它接口对应的理类
StudentMapper proxy = (StudentMapper) dynamicsProxy.getProxy();
proxy.delete();
}
// 目标类
private Object target;
// 通过set方法注入目标类
public void setTarget(Object target) {
this.target = target;
}
优点:
- 一个接口可以通过反射创建多个代理类
- 进需要维护目标类,而代理类是反射动态生成的不需要单独再去维护
更多推荐
所有评论(0)