1.概念:类似于装饰模式,不需要定义大量的装饰类,不改变源代码,增加新的功能。(动态代理)
2.场景
//2.1.创建JavaBean

1 package com.bc; 2 3 public class Person { 4 private String name; 5 6 public Person() { 7 } 8 public String getName() { 9 return name; 10 } 11 public void setName(String name) { 12 this.name = name; 13 } 14 }
//2.2创建JavaBean的接口

1 package com.bc; 2 3 public interface PersonDao { 4 public void insert(Person p);//新增 5 public void update(Person p);//修改 6 }
//2.3创建JavaBean的实现类

1 package com.bc; 2 3 public class PersonDaoImpl implements PersonDao{ 4 public void insert(Person p) { 5 System.out.println("增加一个person"); 6 } 7 public void update(Person p) { 8 System.out.println("修改一个person"); 9 } 10 }
//2.4创建调用处理器实现代理接口

1 package com.bc; 2 import java.lang.reflect.InvocationHandler; 3 import java.lang.reflect.Method; 4 /** 5 * 调用处理器 6 */ 7 public class MyInvocationHandler implements InvocationHandler { 8 //目标对象 9 private Object target; 10 //构造函数传参 11 public MyInvocationHandler(Object target){ 12 this.target=target; 13 } 14 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 15 System.out.println("hello spring boot"); 16 Object obj=method.invoke(target,args);//此返回值代表方法的类型 17 return obj; 18 } 19 }
//2.5使用动态代理实现调用PersonDaoImpl的insert方法

1 package com.bc; 2 3 import java.lang.reflect.Proxy; 4 public class App { 5 public static void main(String args[]){ 6 //得到系统ClassLoader 7 ClassLoader loader=ClassLoader.getSystemClassLoader(); 8 //接口数组 9 Class[] classes = {PersonDao.class}; 10 //目标对象 11 PersonDao dao =new PersonDaoImpl(); 12 //处理器 13 MyInvocationHandler h = new MyInvocationHandler(dao); 14 //动态创建代理对象 15 PersonDao proxy=(PersonDao) Proxy.newProxyInstance(loader,classes,h); 16 proxy.insert(new Person()); 17 } 18 }
//输出:
hello spring boot
新增一个person
注:即在不修改原来方法的前提下,新增功能。
3.流程
说明:在App客户端中,创建动态代理,代理执行目标方法,此时会去执行代理中的invoke方法,在invoke方法执行目标方法之前或者之后,可加入新的功能,执行目标方法的时候,目标对象会将该方法的返回值返回给invoke方法,此时invoke的结果再返回给客户端中的代理的执行结果。