java两种代理模式

简单设计动态代理,基本模拟spring的动态代理方式。before afterReturning around afterException after这些通知方法都可以这块模拟出来spring的AOP: 1.在容器中的对象如果实现了接口则采用JDK的动态代理。2在容器中的对象没有实现接口,则用(cglib)继承的方式实现动态代理。现在模拟spring的动态代理。首先准备接口(UserService)和实现接口的目标对象(UserServiceImpl)。 1 public interface UserService {2 3 void save(); 4 5 }

1 public class UserServiceImpl implements UserService {2 3 public void save() {4 System.out.println("保存用户");5 } 6 7 }

1.动态代理

1 /** 2* 动态代理1 3* 4* @author shihaibin 5* @param <T> 6* 7 */ 8 public class UserServiceProxyFactory implements InvocationHandler { 9 10 Object impl;11 12 public <T> Object getProxy(Class<T> clz) {13 try {14 impl = clz.newInstance();15 } catch (InstantiationException e) {16 // TODO Auto-generated catch block17 e.printStackTrace();18 } catch (IllegalAccessException e) {19 // TODO Auto-generated catch block20 e.printStackTrace();21 }22 // 生成动态代理23 Object usProxy = Proxy.newProxyInstance(clz.getClassLoader(), clz.getInterfaces(), this);24 // 返回25 return usProxy;26 }27 28 /**29* 参数:1.当前代理對象 2.当前方法 3.当前方法执行的时候的参数30 Java初高级一起学习分享,共同学习才是最明智的选择,喜欢的话可以我的学习群64弍46衣3凌9,或加资料群69似64陆0吧3*/

31 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {32 before();33 Object invoke = method.invoke(impl, args);34 after();35 return invoke;36 }37 //可以重写38 public void before() {39 System.out.println("之后");40 }41 42 public void after() {43 System.out.println("之后");44 }45 }

测试:

1 @Test2 public void find1() {3 // 简单的aop4 UserServiceProxyFactory factory = new UserServiceProxyFactory();5 UserService userServiceProxy = (UserService) factory.getProxy(UserServiceImpl.class);6 userServiceProxy.save(); 7 System.out.println(userServiceProxy instanceof UserServiceImpl);8 }

2.cglib代理

1 /** 2* 动态代理2 cglib代理 3* 4* @author shihaibin 5* 6 */ 7 public class UserServiceProxyFactory2 implements MethodInterceptor { 89 public <T> Object getProxy(Class<T> clz) {10 Enhancer en = new Enhancer();// 帮我们生成代理对象11 en.setSuperclass(clz);// 设置对谁进行代理12 en.setCallback(this);//回调函数13 return en.create();// 创建代理对象;14 }15 16 /**17* prxoyobj:被代理的原始对象 method:被代理的原始方法 arg:运行期的参数 methodProxy:产生的代理方法18 */19 public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {20 // 打开事务21 System.out.println("打开事务!");22 // 调用原有方法23 Object invokeSuper = methodProxy.invokeSuper(prxoyobj, arg);24 // 提交事务25 System.out.println("提交事务!");26 return invokeSuper;27 }28 }

测试:

1 @Test 2 public void find2() { 3 // 重写aop前后方法 4 UserServiceProxyFactory2 factoryContext = new UserServiceProxyFactory2(); 5 UserService userServiceProxy = (UserService) factoryContext.getProxy(UserServiceImpl.class); 6 userServiceProxy.save(); 7 // 判断代理对象是否属于被代理对象类型 8 // 代理对象继承了被代理对象=>true 9 System.out.println(userServiceProxy instanceof UserServiceImpl);// 判断是否属于被代理对象类型10 }