1.静态代理
总共只有两个类,代理类和被代理类。其中代理类是被代理类的增强和扩展
被代理的类C和代理类B都要实现同一个接口
代理类B中调用代理类C中相同的方法
interface D
{
public void function1();
}
class C implements D
{
@Override
public void function1()
{
System.out.println("111111");
}
}
class B implements D
{
private C c;
//构造方法
public B(C c)
{
this.c=c;
}
@Override
public void function1()
{
c.function1();
}
//除了和被代理的类有相同的function1之外,代理类本身额外还有独有的方法function2
public void function2()
{
System.out.println("2222222");
}
}
public class A
{
public static void main(String[] args)
{
C c=new C();
B b=new B(c);
b.function1();
}
}
上面代码的结构不够清晰,看看下面的图就清晰了:
本来是客户端代码想要直接调用类C的function1()方法的,但是有了代理类后,通过调用代理类B的function1()方法来间接调用类C的function1()方法
可以看到代理类其实就是被代理类的增强,代理类除了有被代理类的方法, 还有被代理类中没有的方法
下面这张图也写得挺好的:很直观的表明了代理类就是被代理类的增强和扩展
2.动态代理 又叫JDK代理
代理类不需要实现接口,被代理类还是要实现接口
java.lang.reflect这个包里面有一个类,叫作Proxy类,这个类有一个核心方法newProxyInstance()
该方法需要接收三个参数:
(1)ClassLoader loader:用于加载代理类的类加载器
(2)Class<?>[] interfaces:需要代理的接口列表
(3)InvocationHandler h:实现InvocationHandler接口的实例
newProxyInstance(ClassLoader loader,Class<?>[] interfaces,nvocationHandler h){
xxxxxxxxxxxxxxxxxxxxx;
}
该方法返回一个代理对象,该对象实现了指定接口列表中的所有接口,你要执行被代理类C的function1()方法,只需要执行代理对象的function1()方法即可
3.Cglib动态代理
静态代理要求代理类和被代理类都实现接口
动态代理要求被代理类实现接口,代理类可以不实现接口
而Cglib动态代理允许代理类和被代理类都不实现接口
Spring AOP如何选择代理模式:
(1)代理类需要实现接口时,就采用jdk动态代理
(2)代理类不需要实现接口时,就采用Cglib动态代理
其实Cglib动态代理和jdk动态代理代码很像,只是Cglib动态代理允许代理类和被代理类都不实现接口