代理:辅助对象处理一些操作,为对象的行为做代理(明星的经纪人)。
动态代理调用方法的流程

实现动态代理的步骤
动态代理例子
- //被代理对象的技能接口
- public interface Skill {
- void sing();
- void dance();
- }
-
- //明星类(实现Skill接口)
- public class Star implements Skill{
- String name;
- public Star(String name) {
- this.name = name;
- }
- @Override
- public void sing() {
- System.out.println(name + "开始唱《爱你》");
- }
- @Override
- public void dance() {
- System.out.println(name + "开始跳宅舞");
- }
- }
-
- //明星的代理人类
- public class StarAgent {
- public static Skill getProxy(Star obj) {
- //3.用传入的被代理对象构造代理对象,并以接口类型返回
- return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
- @Override
- //method:传入的方法 args:传入的参数
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- //4.额外的操作(动态代理的目的)
- System.out.println("收首付款");
- //5.真正调用被代理对象的方法
- Object result = method.invoke(obj,args);
- System.out.println("收尾付款");
- return result;
- }
- });
- }
- }
-
- //测试类
- public class Test {
- public static void main(String[] args) {
- //1.实例化被代理的对象
- Star s1 = new Star("杨超越");
- //2.将被代理对象传入代理类方法
- Skill s2 = StarAgent.getProxy(s1);
- //6.实际是通过代理对象调用的方法
- s2.sing();
- s2.dance();
- }
- }
-
-
- 输出结果:
- 收首付款
- 杨超越开始唱《爱你》
- 收尾付款
- 收首付款
- 杨超越开始跳宅舞
- 收尾付款
动态代理的作用
在不改变方法源码的情况下,增强方法功能,提高复用性
提高开发效率和可扩展性
可为被代理对象所有方法做代理
可以为任意接口的实现类对象做代理
- public class StarAgent {
- //将接口类型改为T(任意类型)
- public static
T getProxy(T obj) { - return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
- @Override
- //method:传入的方法 args:传入的参数
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- System.out.println("收首付款");
- Object result = method.invoke(obj,args);
- System.out.println("收尾付款");
- return result;
- }
- });
- }
- }