定义:是指对其他对象提供一种代理,以控制对这个对象的访问,代理对象在服务端和目标对象之间起到中介作用
使用场景:1、保护目标对象, 2、增强目标对象功能
静态代理举例:
public class Zhangsan implements IPerson {
@Override
public void findLove() {
System.out.println("肤白貌美大长腿");
}
}
public class Zhanglaosan implements IPerson {
private Zhangsan zhangsan;
public Zhanglaosan(Zhangsan zhangsan) {
this.zhangsan = zhangsan;
}
@Override
public void findLove() {
System.out.println("要孝顺!");
zhangsan.findLove();
System.out.println("能生娃");
}
}
public class Test {
public static void main(String[] args) {
Zhanglaosan zhanglaosan =new Zhanglaosan(new Zhangsan());
//通过调用张三他爸这个代理对象实现张三找对象这个事情,同时还能对张三找对象这个问题进行增强
zhanglaosan.findLove();
}
}
jdk动态代理和cglib动态代理的本质区别:
cglib是代理类直接继承(继承子类就有了父类的方法)目标类的,不需要实现接口(重写接口所有方法);
jdk目标类实现了接口;
jdk动态代理需要获取目标类的所有接口作为生产代理对象的参数
sping源码中会去判断类是否实现接口,若实现接口则使用jdk动态代理,若没有实现接口会使用cglib动态代理,(优先使用jdk动态代理)
可以手动配置强制使用cglib动态代理模式生产代理对象
java动态代理
public interface IPerson {
void findLove();
void buy();
}
public class JdkProxy implements InvocationHandler{
private IPerson targer;
public IPerson getInstance(IPerson targer){
this.targer = targer;
Class<? extends IPerson> targerClass = targer.getClass();
//argerClass.getInterfaces()不关心目标对象实现的接口是什么(随便是人还是动物都可以,比较灵活)
//静态代理是硬编码(父亲),
//argerClass.getInterfaces() jdk动态代理目标对象需要实现接口,区别于cglib
return (IPerson) Proxy.newProxyInstance(targerClass.getClassLoader(), targerClass.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beforeMethod();
Object result = method.invoke(this.targer, args);
afterMethod();
return result;
}
private void afterMethod() {
System.out.println("代理对象后面干点啥");
}
private void beforeMethod() {
System.out.println("代理对象前面干点啥");
}
}
public class Lisi implements IPerson {
@Override
public void findLove() {
System.out.println("有才华");
}
@Override
public void buy() {
System.out.println("买个平安保险");
}
}
public class Zhangsan implements IPerson {
@Override
public void findLove() {
System.out.println("肤白貌美大长腿");
}
@Override
public void buy() {
System.out.println("买个人寿保险");
}
}
public class Test {
public static void main(String[] args) {
JdkProxy jdkProxy = new JdkProxy();
//左边lisi对象已经不是右边李四对象了,而是一个通过字节码生成的一个代理对象
IPerson lisi = jdkProxy.getInstance(new Lisi());
lisi.findLove();
lisi.buy();
IPerson zhangsan = jdkProxy.getInstance(new Zhangsan());
zhangsan.findLove();
zhangsan.buy();
}
}
cglib动态代理
public class CglibProxy implements MethodInterceptor{
//cglib是直接继承(继承子类就有了父类的方法)目标类的,不需要实现接口(重写接口所有方法)
public Object getInstance(Class<?> clazz){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
private void afterMethod() {
System.out.println("代理对象后面干点啥");
}
private void beforeMethod() {
System.out.println("代理对象前面干点啥");
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
beforeMethod();
Object result = methodProxy.invokeSuper(o, objects);
afterMethod();
return result;
}
}
public class Zhangsan{
public void findLove() {
System.out.println("高挑的");
}
public void buy() {
System.out.println("买个cglib保险");
}
}
public class Test {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
Zhangsan zhangsanProxy = (Zhangsan)cglibProxy.getInstance(Zhangsan.class);
zhangsanProxy.findLove();
zhangsanProxy.buy();
}
}
网友评论