目前java动态代理的实现分为两种
- 基于JDK的动态代理(面向接口)
- 基于CGILB的动态代理(面向父类)
作用
在业务中使用动态代理,一般是为了给需要实现的方法添加预处理或者添加后续操作,但是不干预实现类的正常业务,把一些基本业务和主要的业务逻辑分离。我们一般所熟知的Spring的AOP原理就是基于动态代理实现的
基于JDK的动态代理
基于JDK的动态代理就需要知道两个类:1.InvocationHandler(接口)、2.Proxy(类)
第一步、创建一个接口
1 2 3 4 5 6 7 8 9
| package dynamicProxy;
public interface Subject { void hello(String param); }
|
第二步、实现接口
1 2 3 4 5 6 7 8 9 10 11 12
| package dynamicProxy;
public class SubjectImpl implements Subject{ @Override public void hello(String param) { System.out.println("Hello World"); } }
|
第三步、创建SubjectImpl的代理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package dynamicProxy;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;
public class SubjectProxy implements InvocationHandler {
private Subject subject;
public SubjectProxy(Subject subject){ this.subject = subject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("--------begin-------"); Object invoke = method.invoke(subject, args); System.out.println("---------end--------"); return invoke; } }
|
第四步、编写代理类的实际调用,利用Proxy类创建代理之后的Subject类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package dynamicProxy;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy;
public class Test { public static void main(String[] args) { Subject subject = new SubjectImpl(); InvocationHandler subjectProxy = new SubjectProxy(subject);
Subject subjectProxy1 = (Subject) Proxy.newProxyInstance( subjectProxy.getClass().getClassLoader(), subject.getClass().getInterfaces(), subjectProxy ); subjectProxy1.hello(""); } }
|
基于CGLIB的动态代理
因为基于JDK的动态代理一定要继承一个接口,而绝大部分情况是基于POJO类的动态代理,那么CGLIB就是一个很好的选择,在Hibernate框架中PO的字节码生产工作就是靠CGLIB来完成的。
引入CGLIB jar包
1 2 3 4 5
| <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
|
创建代理类
1 2 3 4 5 6 7 8 9 10 11
| package dynamicProxy;
public class CGSubject { public void hello(String param){ System.out.println("hello" + param); } }
|
实现MethodInterceptor接口,对方法进行拦截
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package dynamicProxy;
import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class HelloInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("----------begin---------"); Object object = methodProxy.invokeSuper(o, objects); System.out.println("-----------end-----------"); return object; } }
|
创建被代理的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package dynamicProxy;
import net.sf.cglib.proxy.Enhancer;
public class CGTest { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(CGSubject.class); enhancer.setCallback(new HelloInterceptor()); CGSubject cgSubject = (CGSubject) enhancer.create(); cgSubject.hello("zhangsan"); } }
|