动态代理是为了实现Aop编程(不修改类源码,类方法执行前后,自定义增强处理, 日志 拦截等等),代理的是类对象
jdk动态代理
被代理的类需要实现接口,针对接口的代理,通过生成一个实现了接口的动态类实现代理
ServiceImpl是被代理类,实现接口ServiceInterface
JDKProxy是代理处理方法类,实现接口InvocationHandler
通过JDKProxy.bind()得到jdk【动态生成】代理类ServiceProxy (ServiceInterface)
当你调用ServiceProxy.doService()会执行JDKProxy的invoke()方法,实现代理
//ServiceInterface.java
public interface ServiceInterface {
public void doService();
}
//ServiceImpl.java
public class ServiceImpl implements ServiceInterface {
public void doService() {
System.out.println("ServiceImpl");
}
}
//JDKProxy.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy implements InvocationHandler {
private Object target = null;
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before method:"+method.getName());
Object res = method.invoke(target,args);
System.out.println("after method");
return res;
}
public static void main(String[] args) {
ServiceInterface service = (ServiceInterface) new JDKProxy().bind(new ServiceImpl());
service.doService();
}
}
cglib动态代理
通过生成被代理类的【子类】实现代理,所以 Cglib是无法代理final修饰的方法或类
ServiceImpl是被代理类
ServiceProxy是代理处理类,实现接口MethodInterceptor
通过ServiceProxy.getProxy()动态生成被代理类子类ServiceImpl_SubClass (ServiceImpl)
当你调ServiceImpl_SubClass.doService()会执行ServiceProxy.Intercept()方法,实现代理
//ServiceInterface.java
public interface ServiceInterface {
public void doService();
}
//ServiceImpl.java
public class ServiceImpl implements ServiceInterface{
public void doService() {
System.out.println("ServiceImpl");
}
}
//ServiceProxy.java
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class ServiceProxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz) {
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before method:" + method.getName());
Object res = methodProxy.invokeSuper(o, objects);
System.out.println("after method");
return res;
}
public static void main(String[] args) {
ServiceInterface service = (ServiceImpl) new ServiceProxy().getProxy(ServiceImpl.class);
service.doService();
}
}
//pom.xml
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
上面的jdk与cglib动态代理例子,没有改变ServiceInterface接口与ServiceImpl实现类代码,通过一个代理处理类实现动态对ServiceImpl的代理,方法执行前后增强处理,打印日志,也可以通过try catch捕获方法中的异常实现事务控制等等