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 {@Overridepublic void addUser() {System.out.println("addUser");}@Overridepublic void updateUser() {System.out.println("updateUser");}@Overridepublic 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() {@Overridepublic 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 {@Testpublic 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);*/} }