java 进阶一:代理和动态代理
静态代理:
定义顶级接口:Iservice
//目标类和代理类都实现该接口 public interface Iservice { public String server(); }
定义目标类:ServiceImp 实现 Iservice接口
// 目标类 public class ServiceImp implements Iservice { @Override public String server() { return "hello"; } }
定义代理类:ServiceProxy 实现 Iservice 接口,将目标类中目标方法的返回值变为大写字符
// 代理类 public class ServiceProxy implements Iservice { Iservice target; public ServiceProxy() { } public ServiceProxy(Iservice target) { this.target = target; } @Override public String server() { return target.server().toUpperCase(); } }
测试:
public class Test { public static void main(String[] args) { Iservice target=new ServiceImp(); Iservice proxy=new ServiceProxy(target); System.out.println(proxy.server()); } }
动态代理的两种实现方式
1、使用JDK的Proxy实现代理,要求目标类和代理类实现相同的接口。若目标类不存在接口,则无法使用该方式实现。
2、对于无接口的类,需要使用CGLIB来实现代理。CGLIB代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类就是代理对象。因此,使用CGLIB生成动态代理,要求目标类必须能被继承,即不能是final修饰的类。
CGLIB(Code Generation Library)是一个开源项目,是一个强大的、高性能的、高质量的代码生成类库。它可以在运行期间扩展和增强java类。Hibernate用它来实现持久对象的字节码的动态生成,Spring用它来实现AOP编程。CGLIB包的底层是通过使用字节码处理框架ASW(Java字节码处理框架),来转换字节码并生成新的类。CGLIB是通过对字节码进行增强来生成代理的。
相关实例代码:
1、Proxy实现:
public class Test { public static void main(String[] args) { // 定义目标对象 Iservice target=new ServiceImp(); // 定义目标对象的代理对象 Iservice myproxy=(Iservice) Proxy.newProxyInstance( target.getClass().getClassLoader(), // 目标类的类加载器 target.getClass().getInterfaces(), //目标类实现的接口 new InvocationHandler() { // proxy:代理对象 // method:目标方法 // args:目标方法的参数 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result=method.invoke(target, args); if ("server".equals(method.getName())) { result = result.toString().toUpperCase(); } return result; } }); System.out.println(myproxy.server()); } }
2、CGLIB实现:
定义目标类:Service
public class Service { public String server(){ return "hello"; } }
创建cglib代理:
import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor { private Service target; public CglibProxy() { } public CglibProxy(Service target){ this.target=target; } // 创建cglib代理对象 public Service myProxy(){ Service service=new Service(); Enhancer enhancer=new Enhancer(); // 指定父类,即要增强的目标类 enhancer.setSuperclass(Service.class); // 指定回调接口对象 enhancer.setCallback(this); // 创建cglib代理对象 return (Service) enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object result=method.invoke(target, args); if ("server".equals(method.getName())) { result = result.toString().toUpperCase(); } return result; } }
测试:
public class Test { public static void main(String[] args) { // 创建目标对象 Service target=new Service(); // 创建目标对象的代理对象 Service proxy=new CglibProxy(target).myProxy(); System.out.println(proxy.server()); } }