Java动态代理和静态代理模式的区别有哪些?

Java动态代理和静态代理模式

什么是动态代理?

现实生活中火车票代理售后点:买票,退票,代理点购票。购买方式有直接到火车站售票点购买,或者去火车票代售点购买火车票。

此时,代售点就是代理中介(具有购买,和退票)。

画图理解

举个例子:假设火车站有购买车票方法和退票的方法,代理售票点也有购买车票和退票方法。

image-20220426094840334

动态代理-实现代理购买火车票

  • 创建火车站购买车票接口
/**
 * 火车票购买窗口
 * @author jkl
 *
 */
public interface ChooseService {
	
	//购买火车票
	public void buyTicket(String name);
	//退火车票窗口
	public void exitTicket(String name);

}

  • 创建火车站购买车票实现接口类(委托类)
public class ChooseServiceImpl implements ChooseService{

	@Override
	public void buyTicket(String name) {
		System.out.println("通过---["+name+"]---购买了车票");
	}

	@Override
	public void exitTicket(String name) {
		System.out.println("通过---【"+name+"---】退了车票");
	}

}
  • 创建jdk动态代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * jdk动态代理类对象
 * @author jkl
 *
 */
public class MyChooseProxyHandler implements InvocationHandler{

	private Object target ;
	
	//设置代理接口类
	public void setInterface(Object target){
		this.target=target;
	}
	//获取被代理类对象
	public Object getProxy(Object target){
		//System.out.println("使用当前类的ChooseService:"+this.getClass().getClassLoader());
		//System.out.println("当前类对象的接口ChooseService:"+target.getClass().getInterfaces());
		//System.out.println("当前类对象MyChooseProxyHandler:"+this);
		Object result = Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
		return result;
	}
	/**
	 * proxy : 代理对象
	 * methode:代理方法
	 * args: 代理参数
	 * 处理代理实例并返回结果
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object result= 	method.invoke(target, args);
		logs(method.getName());
		return result;
	}
	
	/**
	 * 日志记录方法处理
	 */
	public void logs(String method){
		System.out.println("操作日志记录了"+method+"方法");
	}

}
  • 测试jdk动态代理
public class ChooseController {
	
	public static void main(String[] args) {
		ChooseService choose = new ChooseServiceImpl();
		choose.buyTicket("火车站");
		MyChooseProxyHandler handler = new MyChooseProxyHandler();
		handler.setInterface(choose);
		ChooseService service = (ChooseService) handler.getProxy(choose);
		service.buyTicket("代理售后点");
		service.exitTicket("代理售后点");
	}

}
  • 输出结果:
通过---[火车站]---购买了车票
通过---[代理售后点]---购买了车票
操作日志记录了buyTicket方法
通过---【代理售后点---】退了车票
操作日志记录了exitTicket方法

静态代理-实现案例

  • 创建用户接口类
package com.urun.proxy.users;

public interface UserService {
	
	public void add(String name);
	public void update(String id);
	public void delete(String id);
	public void getAll();

}
  • 创建用户接口实现类
package com.urun.proxy.users;

public class UserServiceImpl implements UserService {

	@Override
	public void add(String name) {
		System.out.println(name+"新增用户信息");
	}

	@Override
	public void update(String id) {
		System.out.println("编辑用户信息");
	}

	@Override
	public void delete(String id) {
		System.out.println("删除用户信息");
		
	}

	@Override
	public void getAll() {
		System.out.println("查询所有用户信息");
		
	}

}
  • 创建静态代理类
package com.urun.proxy.users;
/**
 * 静态代理
 * @author jkl
 *
 */
public class UserServiceProxy implements UserService{

	private UserServiceImpl userService;
	
	public void setUserService(UserServiceImpl userService) {
		this.userService = userService;
	}
	
	@Override
	public void add(String name) {
		userService.add(name);
		this.logs("add");
	}

	@Override
	public void update(String id) {
		userService.update(id);
		this.logs("update");
	}

	@Override
	public void delete(String id) {
		userService.delete(id);
		this.logs("delete");
	}

	@Override
	public void getAll() {
		userService.getAll();
		this.logs("getAll");
	}
	
	public void logs(String msg){
		System.out.println("扩展业务:操作日志"+msg);
	}

}
  • 测试静态代理
package com.urun.proxy.users;

public class UserClient {
	
	public static void main(String[] args) {
		UserServiceImpl userService = new UserServiceImpl();
		UserServiceProxy proxy = new UserServiceProxy();
		proxy.setUserService(userService);
		proxy.add("静态代理:");
		proxy.delete("001");
	}

}

输出结果:

静态代理:新增用户信息
扩展业务:操作日志add
删除用户信息
扩展业务:操作日志delete

Java动态代理源码分析

InvocationHandler接口类
public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

invoke方法

   @CallerSensitive
    public Object invoke(Object obj, Object... args)
        throws IllegalAccessException, IllegalArgumentException,
           InvocationTargetException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        MethodAccessor ma = methodAccessor;             // read volatile
        if (ma == null) {
            ma = acquireMethodAccessor();
        }
        return ma.invoke(obj, args);
    }
Proxy接口类
	//生成得到代理类
public Object getProxy(){
		
		Object object =	Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
		
		return object;
}

newProxyInstance方法源码

@CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);

        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * Look up or generate the designated proxy class.
         */
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }

            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }

总结分析动态代理和静态代理的区别?

1.动态代理实现原理

​ 动态代理基于Java反射机制完成,静态代理通过类实现注入依赖完成。

2.优缺点:

​ 2.1.动态代理只能实现类已经实现的接口代理,不能对类直接代理,可以接口任意一个方法

​ 扩展和操作,不需要全部实现接口的所有方法。

​ 2.1.静态代理的类需要实现全部被代理的接口类的方法,对于不需要扩展的方法造成代码冗

3.代理的流程
代理的四要素:代理对象、被代理的行为、被代理的对象、行为的完全控制

spring cglib动态代理实现案例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唂雨云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值