静态代理和动态代理
- 代理模式
- 代理模式的主要优缺点:
- 优点:
- 缺点:
- 代理模式的编写要点
- 静态代理实现步骤
- 静态代理方式的弊端
- 动态代理:
- 动态代理的实现步骤:
代理模式
代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
代理模式的主要优缺点:
优点:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;
缺点:
- 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
- 增加了系统的复杂度;
代理模式的编写要点
-
和被代理对象实现相同的接口
-
在代理类中,需要对被代理对象初始化
-
需要实现和被dialing对象相同的方法,并且在这个方法中核心(原始)业务调用被代理对象的,增强的业务在这里进行增强就行了
静态代理实现步骤
- 定义业务接口(代理类和被代理类都要实现此接口)
public interface Person {
void eat();
}
- 创建被代理类实现业务接口
public class Student implements Person{
@Override
public void eat() {
System.out.println("学生在买饭");
}
}
- 创建代理类实例化被代理类并实现业务接口
public class Teacher implements Person{
private Student s ;
public Teacher(){
this.s = new Student();
}
@Override
public void eat() {
s.eat();
}
}
- 主方法调用代理类
public class Test {
public static void main(String[] args) {
Teacher t = new Teacher();
t.eat();
}
}
- 实现被代理类的业务
静态代理方式的弊端
- 如果有很多个对象需要找代理,那么就需要实现很多个对象的代理类,这样的话代码臃肿,用户体验很一般;
- 如果被代理的方法过多,每个方法都需要增强,代码不整洁,大量搬用的工作 它有这两大缺陷就造成了写大型项目的时候,就不会用静态代理这个设计模式
动态代理:
在程序执行过程中,使用jadk的反射机制,创建代理类对象,并动态的指定要代理目标类。
动态代理是使用jd的反射机制,创建对象的能力,创建的是代理类的对象。而不用你创建类文件。不用写java文件。
动态代理的实现步骤:
- 创建接口,定义目标类要完成的功能
public interface Person {
void eat();
}
- 创建目标类实现接口
public class Student implements Person{
@Override
public void eat() {
System.out.println("学生去买饭");
}
}
- 创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
1.调用目标方法
2.增强功能
public class Teacher implements InvocationHandler {
private Person person;
public Object prxy() {
return Proxy.newProxyInstance(person.getClass().getClassLoader(),
person.getClass().getInterfaces(),this);
}
public Teacher(Person person) {
this.person = person;
}
// 1.调用目标方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 2.增强功能
System.out.println("老师要吃饭");
System.out.println("小花给我买饭去");
method.invoke(person,args);
System.out.println("老师吃饭了");
return null;
}
}
- 使用Proxy类的静态方法,创建代理对象。并把返回值转为接口类型。
public class Test {
public static void main(String[] args) {
Student student = new Student();
Teacher teacher = new Teacher(student);
Person ob = (Person)teacher.prxy();
ob.eat();
}
}