动态代理,
1)代理对象,不需要实现接口;
2)代理对象的生成,是利用JDKAPI, 动态的在内存中构建代理对象(需要我们指定创建 代理对象/目标对象 实现的接口的类型;);
3) 动态代理, JDK代理, 接口代理;
JDK中生成代理对象的API:
|-- Proxy static Object newProxyInstance( ClassLoader loader, 指定当前目标对象使用类加载器 Class<?>[] interfaces, 目标对象实现的接口的类型 InvocationHandler h 事件处理器 )
思考:
有一个目标对象,想要功能扩展,但目标对象没有实现接口,怎样功能扩展?
Class UserDao{}
// 子类的方式
Class subclass extends UserDao{}
以子类的方式实现(cglib代理)
package loaderman.b_dynamic; // 接口 public interface IUserDao { void save(); }
package loaderman.b_dynamic; /** * 目标对象 * */ public class UserDao implements IUserDao{ @Override public void save() { System.out.println("-----已经保存数据!!!------"); } }
package loaderman.b_dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 给所有的dao创建代理对象【动态代理】 * * 代理对象,不需要实现接口 * */ public class ProxyFactory { // 维护一个目标对象 private Object target; public ProxyFactory(Object target){ this.target = target; } // 给目标对象,生成代理对象 public Object getProxyInstance() { return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开启事务"); // 执行目标对象方法 Object returnValue = method.invoke(target, args); System.out.println("提交事务"); return returnValue; } }); } }
package loaderman.b_dynamic; public class App { public static void main(String[] args) { // 目标对象 IUserDao target = new UserDao(); // 【原始的类型 class cn.loaderman.b_dynamic.UserDao】 System.out.println(target.getClass()); // 给目标对象,创建代理对象 IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance(); // class $Proxy0 内存中动态生成的代理对象 System.out.println(proxy.getClass()); // 执行方法 【代理对象】 proxy.save(); } }