JDK动态代理
Jdk动态代理是装饰模式的一个典型用例,关于装饰模式这里不多解释,直接说重点吧.jdk动态代理实际上就是代替继承方案,在不破坏原始类的原则下,在运行期间为某个类动态注入一些新的方法。java.lang.reflect.Proxy提供了生成代理类的接口。进入源代码,我们可以看见关于Proxy的详细说明这里截取一些关键的部分:
/** * {@code Proxy} provides static methods for creating dynamic proxy * classes and instances, and it is also the superclass of all * dynamic proxy classes created by those methods. *(Proxy提供了提供了一系列生成动态代理类或实例静态的方法,它是所有动态代理类的超类) * 目标类:就是你要代理的对象 * 代理类:代理目标类执行动作的类 * * <p>To create a proxy for some interface {@code Foo}: *(给目标类添加一些方法(接口)生成代理类的方法:) * <pre> * //获取自定义处理类对象 * InvocationHandler handler = new MyInvocationHandler(...); * //获取代理类字节码对象 * Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class); * //生成代理类对象实例 * Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class). * newInstance(handler); * </pre> * or more simply:(也可以用如下更简单的方式:) * <pre> * //这里使用了匿名内部类的方式,直接将处理逻辑推迟到用户具体定义使用的时候,具有极大的灵活性 * * //Foo.class.getClassLoader()获取类加载器,以便将代理类注册到内存,实际上这里是指虚拟机 * //new Class<?>[] { Foo.class } 获取目标类所有的方法(接口) * //handler 自定义的处理逻辑,也就是说你拿到方法后要干什么 * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), * new Class<?>[] { Foo.class }, * handler); * </pre>
官方已经详细介绍了这个接口的使用方法,同时也对其中的原理做了阐述,这里就直接上实例来说说具体用法吧,jdk动态代理的实现原理 这种鬼东西至少也要在你会用的基础上再研究吧,等你会用了,自
己直接看源码去,以你的智商那还不是小ks。
- 目标类接口设计
-
package com.heima_aop; public interface UserService { public void addUser(); public void updateUser(); public void deleteUser(); }
- 目标类接口实现
-
package com.heima_aop; public class UserServiceImpl implements UserService { @Override public void addUser() { System.out.println("addUser"); } @Override public void updateUser() { System.out.println("updateUser"); } @Override public void deleteUser() { System.out.println("deleteUser"); } }
- 代理类设计
-
package com.heima_aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Proxy; public class ProxyFactoryBean { public static UserService createUserService() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { // 目标类 final UserService service = new UserServiceImpl(); // 切面类 final MyAspect aspect = new MyAspect(); //处理类 MyInvocationHandler handler = new MyInvocationHandler(service); /** * 生成代理对象字节码 */ Class<?> proxyClass = Proxy.getProxyClass(ProxyFactoryBean.class.getClassLoader(), new Class[]{UserService.class}); /** * 使用反射调用代理类对象的构造函数,通过InvocationHandler接口进行规范,InvocationHandler的接口实现类对象告知其具体处理方式 */ UserService proxy = (UserService) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler); /* * 方法二: * UserService proxy = (UserService) Proxy.newProxyInstance( ProxyFactoryBean.class.getClassLoader(), new Class[] { UserService.class }, new MyInvocationHandler(service)); 方法三:(使用匿名内部类,官方推荐) UserService proxy =(UserService) Proxy.newProxyInstance( ProxyFactoryBean.class.getClassLoader(), new Class[] { UserService.class },InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { aspect.Before(); Object obj = method.invoke(service, args); aspect.After(); return obj; } }); */ return proxy; } }
- 测试
-
package com.heima_aop; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Testdemo { @Test public void test_jdk(){ String xmlpath = "com/heima_aop/bean.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlpath); UserService service = (UserService) applicationContext.getBean("Userservice"); service.addUser(); service.deleteUser(); /*System.out.println(service);*/ } }