静态代理其实就是我们的装饰者设计模式,首先定义一个接口类,然后定义这个接口类的实现类,对每一个实现类定义一个代理类,这里面代理类里面传入这个实现类的引用。
1.1 接口类
public interface PersonInterface {
void say();
}
1.2 实现类
public class Students implements PersonInterface{
@Override
public void say() {
System.out.println("会说英语");
}
}
1.3 代理类
public class StudentProxy implements PersonInterface{
private Students students = new Students();
@Override
public void say() {
System.out.println("111");
students.say();
System.out.println("222");
}
}
1.4 测试类
public static void main(String[] args){
PersonInterface students = new StudentProxy();
students.say();
}
动态代理就是程序在运行期间,通过反射机制来实现对原始类的代理。首先定义一个接口类,在定义一个接口类的实现类,然后定义一个代理类。
2.1 接口类
public interface PersonInterface {
void say();
}
2.2 实现类
public class Persons {
public void say() {
System.out.println("会说英语");
}
}
2.3 代理类
public class Proxys implements InvocationHandler {
private Object object;
public Proxys(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("3333");
method.invoke(object,args);
System.out.println("4444");
return null;
}
}
这个动态代理类主要是实现InvocationHandler接口,定义构造方法,里面用来传入代理类的对象,里面的invoke方法有三个参数,分别是proxy,method,args[] ,它们主要对应代理对象,真实对象的方法,真实对象方法的参数。
2.4 测试类
public static void main(String[] args){
Students students = new Students();
InvocationHandler proxys = new Proxys(students);
PersonInterface p =(PersonInterface)Proxy.newProxyInstance(students.getClass().getClassLoader(),students.getClass().getInterfaces(),proxys);
p.say();
}
3.1 静态代理主要是一个实现类对应一个代理类,这样的话,如果实现类比较多的话,那么它将产生许多代理类,是面向接口编程,在编译已经产生与之对应的代理类。
3.2 动态代理使用接口编程,它的优点就是,很多个实现类可以用一个代理类,主要采用反射技术在运行期对实现类进行代理
3.3 cglib主要是因为jdk动态代理必须实现对应的接口,所以cglib就来解决没有接口时的代理,主要是通过字节码技术来实现代理,定义一个类,这个类就是父类被代理的类,然后cglib通过字节码技术生成一个子类,通过子类来完成对里面方法的增强,所以这就需要父类不能用final进行修饰。
3.4 什么时候用cglib代理?什么使用jdk动态代理?
如果是单例类的话,就使用cglib代理,不用产生很多的类,如果产生很多对象时,就是用jdk动态代理,cglib的性能比jdk代理的性能高