首页 > 史丹利工具代理 > Spring 静态代理和动态代理实现

Spring 静态代理和动态代理实现

静态代理是为了在代理类的前后加上各种需要的东西,而且还不改变其本身的方法,实现方法就是在其父类的接口下重新创建一个类,来实现要代理的类的父类,然后重写方法(重写是为了方法名一样,返回值类型和参数一样),在内部调用其被代理类的方法,在前后加上事物,日志,时间之类

接口

package com.sxt.dao;public interface UserDao { public void save() throws Exception;}123456

被代理的类

package com.sxt.dao.impl;import com.sxt.dao.UserDao;public class UserDaoimpl implements UserDao { public void save() throws Exception { System.out.println("调用了save方法保存"); }}1234567891011

代理类

package com.sxt.dao.impl;import com.sxt.dao.UserDao;public class UserProxy implements UserDao { private UserDao dao; public void save() throws Exception { System.out.println("事物,权限, 日志开启"); dao.save(); System.out.println("事物,权限,日志关闭"); } public UserDao getDao() { return dao; } public void setDao(UserDao dao) { this.dao = dao; }}12345678910111213141516171819

调用的时候直接调用代理类,代理类内部会调用被代理的类, 并且前后加了一些东西, 这就是静态代理的实现方法

动态代理 :为了解决静态代理每有一个被代理类就要创建一个代理类的弊端,出现了动态代理,动态代理是把所有东西都抽取出来了

接口

package com.sxt.dao;public interface UserDao { public void save() throws Exception;}123456

被代理的类

package com.sxt.dao.impl;import com.sxt.dao.UserDao;public class UserDaoimpl implements UserDao { public void save() throws Exception { System.out.println("调用了save方法保存"); }}1234567891011

动态代理类:基于兄弟类

package com.sxt.util;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class MyProxy implements InvocationHandler { private Object target;// 被代理者 public Object getProxy(Object o) { this.target=o;//o就是传过来的被代理者 /** * 第一个参数:this.getClass().getClassLoader() - 定义代理类的类加载器 第二个参数:interfaces - 被代理类的父类的接口 第三个参数:h - 指派方法调用的调用处理程序(应该是谁来代理) */ return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } //调用代理类的代理方法 Object proxy 谁来代理 Method method 方法 Object[] args 参数 public Object invoke(Object proxy,Method method,Object[] args) throws Exception{ System.out.println("事物开启"); //target 被代理的那个类 args 要什么参数 Object b返回值 Object b = method.invoke(target, args);//执行你要执行的方法,前后为事物控制 System.out.println("事物结束"); return b; }}12345678910111213141516171819202122232425262728293031

测试

package com.sxt.test;import com.sxt.dao.UserDao;import com.sxt.dao.impl.UserDaoimpl;import com.sxt.util.MyProxy;public class Test { public static void main(String[] args) { /** * 动态代理 */ UserDao dao = new UserDaoimpl();//被代理的对象 MyProxy dt = new MyProxy(); Object proxy = dt.getProxy(dao);//返回出来的就是代理类,只是这个代理类不用你创建,而是系统给你创建好了 try { dt.invoke(proxy,dao.getClass().getDeclaredMethod("save", null), null); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } }}123456789101112131415161718192021222324252627282930313233

基于父类实现动态代理: cglib动态代理. 本质上动态生成了一个被代理目标的子类(要求被代理类不是final修饰的类),通过多态实现功能的加强,当访问代理中的方法时, 委派给MethodInteceptor中的处理程序(intercept方法)进行出来, 在处理程序中添加了业务逻辑和回掉了被代理目标中的方法。

添加cglib-2.2.2.jar

 <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency>12345

动态代理

package com.sxt.util;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 MyProxy1 implements MethodInterceptor { private Object target; public Object getProxy(Object target){ Enhancer enhancer = new Enhancer(); //1.设置基类 enhancer.setSuperclass(target.getClass()); //2.设置回调接口 enhancer.setCallback(this);//MethodInterceptor实现类 //3.创建动态代理 return enhancer.create(); } public Object intercept(Object proxy, Method m, Object[] os, MethodProxy mp) throws Throwable { Object o = m.invoke(target, os); return o; }}1234567891011121314151617181920212223242526272829

测试

package com.sxt.test;import com.sxt.dao.UserDao;import com.sxt.dao.impl.UserDaoimpl;import com.sxt.util.MyProxy1;/** * 用子类做代理 * @author Administrator * */public class Test2 { public static void main(String[] args) { UserDao dao = new UserDaoimpl(); MyProxy1 dt = new MyProxy1(); Object proxy = dt.getProxy(dao); try { dt.intercept(proxy, dao.getClass().getDeclaredMethod("save", null), null,null); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (Throwable e) { e.printStackTrace(); } }}123456789101112131415161718192021222324252627

和上面那个兄弟类出面做事情差不多,只是设置的时候不一样而已

Spring 静态代理和动态代理实现

,可以参考史丹利工具的资料,