代理技术被一些优秀的框架广泛的使用, 比如spring 的中aop 事务就是通过 动态代理和cglib 代理,共同实现的, hibernate 中的懒加载, 通过返回代理对象延迟加载, 下面我们学习java 中的三种代理技术
定义一个通用的接口
package com.zzq.response.test; public interface IUserDao { void save(); }
实现接口
package com.zzq.response.test; public class UserDao implements IUserDao{ public void save() { System.out.println("----已经保存数据!----"); } }
静态代理
要球 : 要实现静态代理, 代理对象和被代理对象一定同时继承同一个父类, 或者是接口,我们用代码演示
静态代理的本质就是通过在加载新的方法中调用原有的方法 我们看代码
package com.zzq.response.test; public class UserDaoProxy implements IUserDao{ //接收保存目标对象 private IUserDao target; public UserDaoProxy(IUserDao target){ this.target=target; } public void save() { System.out.println("开始事务..."); target.save();//执行目标对象的方法 System.out.println("提交事务..."); } }
测试
package com.zzq.response.test; public class test { public static void main(String[] args) { //目标对象 UserDao target = new UserDao(); //代理对象,把目标对象传给代理对象,建立代理关系 UserDaoProxy proxy = new UserDaoProxy(target); proxy.save();//执行的是代理的方法 } }
静态代理是由缺陷的, 因为他每次只能代理一个方法,如果多个呢? 这时候我们就出现了和静态代理对应的动态代理技术,
动态代理
动态代理相对于静态代理来说, 可以实现动态的对方法,进行代理, 也就是弥补了静态代理的缺点,一次书写,指定代理的方法, 该代理方式是通过 接口代理, 也就是说被代理对象必须,要有接口, 不然不能进行动态代理,该代理技术在jdk 中, 因此也叫做jdk代理, 接口代理
动态代理的方法
proxy .newProxyInstance(被代理对象的类加载器,被代理对象的接口,被代理对象具体的代理细节)
我们通过代理进行演示
接口中定义方法
package com.zzq.response.test2; public interface IUserService { void add(); void delete(); void update(); void insert(); }
实现类
package com.zzq.response.test2; public class UserServiceImpl implements IUserService { public void add() { System.out.println("add........"); } public void delete() { // TODO Auto-generated method stub System.out.println("delete........"); } public void update() { // TODO Auto-generated method stub System.out.println("update........"); } public void insert() { // TODO Auto-generated method stub System.out.println("insert........"); } }
实现代理
package com.zzq.response.test2; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class UserServiceProxyFactory { private IUserService userService ; public UserServiceProxyFactory(IUserService userService){ this.userService = userService ; } public IUserService getIUserService(){ return (IUserService) Proxy.newProxyInstance( userService.getClass().getClassLoader() ,userService.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开启事务"); Object invoke = method.invoke(userService, args); System.out.println("关闭事务"); return invoke ; } }); } }
测试
package com.zzq.response.test2; public class App { public static void main(String[] args) { IUserService userService = new UserServiceImpl(); UserServiceProxyFactory userServiceProxyFactory = new UserServiceProxyFactory(userService); IUserService iUserService = userServiceProxyFactory.getIUserService(); iUserService.add(); } }
其实spring aop 事务就是 使用 动态代理, 它整合了动态代理和cglib 代理技术
Cglib 代理
cglib 代理相对于 java 来说属于第三方代理, 他的好处是 ,不用实现接口, 不用继承 , 代理实现原理是, 通过继承原对象的方式进行代理,下面我们来看代码演示
这里代码直接基于 动态代理的基础上进行书写
package cn.itcast.c_proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import cn.itcast.service.UserService; import cn.itcast.service.UserServiceImpl; //观光代码=>cglib代理 public class UserServiceProxyFactory2 implements MethodInterceptor { public UserService getUserServiceProxy(){ Enhancer en = new Enhancer();//帮我们生成代理对象 en.setSuperclass(UserServiceImpl.class);//设置对谁进行代理 en.setCallback(this);//代理要做什么 UserService us = (UserService) en.create();//创建代理对象 return us; } @Override public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable { //打开事务 System.out.println("打开事务!"); //调用原有方法 Object returnValue = methodProxy.invokeSuper(prxoyobj, arg); //提交事务 System.out.println("提交事务!"); return returnValue; } }好了这就是java 中的三种代理技术,其实想想挺简单的, 但是我们在实际开发中不会使用这些技术的, 因为spring 为我们整合好了,但是多知道,没有坏处对吧