你的位置:首页 > Java教程

[Java教程]Spring笔记(三)


静态代理:自己定义的代理类;

动态代理:程序在运行时生成。

一、静态代理:

接口:UserManager:对用户的增删改查。

1 package com.dwr.spring.proxy;2 3 public interface UserManager {4   public void addUser(String username,String password);5   public void deleteUser(int userid);6   public void modifyUser(int userid,String username,String password);7   public void findUser(int userid);8 }

实现类:UserManagerImpl:

 1 package com.dwr.spring.proxy; 2  3 public class UserManagerImpl implements UserManager { 4   @Override 5   public void addUser(String username, String password) { 6     System.out.println("--------UserManagerImpl.addUser()----------"); 7   } 8  9   @Override10   public void deleteUser(int userid) {11     System.out.println("--------UserManagerImpl.deleteUser()----------");12   }13 14   @Override15   public void modifyUser(int userid, String username, String password) {16     System.out.println("--------UserManagerImpl.modifyUser()----------");17   }18 19   @Override20   public void findUser(int userid) {21     System.out.println("--------UserManagerImpl.findUser()----------");22   }

客户端类:调用方法;

1 package com.dwr.spring.proxy;2 3 public class Client {4 5   public static void main(String[] args){6     UserManager userManager = new UserManagerImpl();7     userManager.addUser("Jack","123456");8   }9 }

结果:

 1 --------UserManagerImpl.addUser()---------- 

结果正常显示。

在UserManagerImpl中加入安全性检测:

 1 public void checkSecurity(){ 2 System.out.println("--------UserManagerImpl.checkSecurity()----------"); 3 } 

UserManagerImpl中每个方法都要调用该方法,耦合度提高。使用代理实现类实现该功能:

在代理中:必须要有要控制对象的引用;

将安全检测方法放到代理类中。调用每个方法前进行安全检测,对原有的类的结构并没有破坏,也完成了需求。

UserManagerImplProxy类:

 1 package com.dwr.spring.proxy; 2  3 public class UserManagerImplProxy implements UserManager { 4   private UserManager userManager; 5  6   public UserManagerImplProxy(UserManager userManager){ 7     this.userManager = userManager; 8   } 9 10   public void checkSecurity(){11     System.out.println("--------UserManagerImpl.checkSecurity()----------");12   }13 14   @Override15   public void addUser(String username, String password) {16     checkSecurity();17     this.userManager.addUser(username,password);18   }19 20   @Override21   public void deleteUser(int userid) {22     checkSecurity();23     this.userManager.deleteUser(userid);24   }25 26   @Override27   public void modifyUser(int userid, String username, String password) {28     checkSecurity();29     this.userManager.modifyUser(userid,username,password);30   }31 32   @Override33   public void findUser(int userid) {34     checkSecurity();35     this.userManager.findUser(userid);36   }37 }

客户端测试:

 1 package com.dwr.spring.proxy; 2  3 public class Client { 4  5   public static void main(String[] args){ 6     //使用静态代理模式实现 7     UserManager userManager = new UserManagerImplProxy(new UserManagerImpl()); 8     userManager.addUser("Jack","123456"); 9   }10 }

静态代理模式使我们自己写的,若接口中方法很多,就会很麻烦,这时就需采用AOP来处理!!!

二、动态代理:

既然是动态代理模式就不需要UserManagerImplProxy这个代理类了。

需要声明一个类实现InvocationHandler接口,并定义一个newProxy的方法返回动态代理

 1 package com.dwr.spring.proxy; 2  3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6  7 public class SecurityHandler implements InvocationHandler { 8   private Object targetObject; 9 10   public Object newProxy(Object targetObject){11     this.targetObject = targetObject;12     //返回动态代理13     return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);14   }15 16 17   public void checkSecurity(){18     System.out.println("--------UserManagerImpl.checkSecurity()----------");19   }20 21   @Override22   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {23     checkSecurity();24     Object ret = null;25 26     try {27       //调用目标对象的真实方法,将返回值保存在ret中28       ret = method.invoke(this.targetObject, args);29     } catch (Exception e){30       e.printStackTrace();31     }32     return ret;33   }34 }

客户端测试:

1      SecurityHandler securityHandler = new SecurityHandler();2     UserManager userManager = (UserManager) securityHandler.newProxy(new UserManagerImpl());  //创建代理对象3     userManager.addUser("Tom","123456");

结果:

 1 --------UserManagerImpl.checkSecurity()---------- 2 --------UserManagerImpl.addUser()---------- 

使用动态代理想进行安全检测就进行安全检测;不想检测就不检测,就是这么任性。。。

客户端:

 1 package com.dwr.spring.proxy; 2  3 public class Client { 4  5   public static void main(String[] args){ 6     SecurityHandler securityHandler = new SecurityHandler(); 7     UserManager userManager = (UserManager) securityHandler.newProxy(new UserManagerImpl());//进行了安全检测 8     userManager.addUser("Tom","123456"); 9     System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++");10     UserManager userManager1 = new UserManagerImpl();  //没有进行安全检测11     userManager1.addUser("Lily","123456");12   }13 }

结果:

--------UserManagerImpl.checkSecurity()----------
--------UserManagerImpl.addUser()----------
++++++++++++++++++++++++++++++++++++++++++++++++++
--------UserManagerImpl.addUser()----------

使用CGLib实现:

创建一个类实现MethodInterceptor接口,重写intercept方法:当代理对象的方法被调用时会调用该方法!!

CGlibProxyFactory类:

 1 package com.dwr.spring.proxy; 2  3 import org.springframework.cglib.proxy.Enhancer; 4 import org.springframework.cglib.proxy.MethodInterceptor; 5 import org.springframework.cglib.proxy.MethodProxy; 6  7 import java.lang.reflect.Method; 8  9 public class CGlibProxyFactory implements MethodInterceptor {10 11   private Object targetObject;12 13   public Object newProxy(Object targetObject){14     this.targetObject = targetObject;15     Enhancer enhancer = new Enhancer();16     enhancer.setSuperclass(this.targetObject.getClass());17     enhancer.setCallback(this);18     //返回代理对象19     return enhancer.create();20   }21 22   public void checkSecurity(){23     System.out.println("--------UserManagerImpl.checkSecurity()----------");24   }25 26   /**27    * @param proxy   带来的对象本身28    * @param method  被拦截到的方法29    * @param objects  方法的参数30    * @param methodProxy  方法的代理对象31   */32   @Override33   public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {34     checkSecurity();35     Object ret = null;36 37     try {38       ret = method.invoke(this.targetObject, objects);39     } catch (Exception e){40       e.printStackTrace();41     }42     return ret;43   }44 }

测试:

 1 package com.dwr.spring.proxy; 2  3 public class CGlibProxyTest { 4  5   public static void main(String[] args){ 6     CGlibProxyFactory factory = new CGlibProxyFactory(); 7     UserManagerImpl userManager = (UserManagerImpl) factory.newProxy(new UserManagerImpl()); 8     userManager.addUser("Tom","123456"); 9   }10 }

结果:

--------UserManagerImpl.checkSecurity()----------
--------UserManagerImpl.addUser()----------