静态代理:自己定义的代理类;
动态代理:程序在运行时生成。
一、静态代理:
接口: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 @Override 10 public void deleteUser(int userid) { 11 System.out.println("--------UserManagerImpl.deleteUser()----------"); 12 } 13 14 @Override 15 public void modifyUser(int userid, String username, String password) { 16 System.out.println("--------UserManagerImpl.modifyUser()----------"); 17 } 18 19 @Override 20 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 @Override 15 public void addUser(String username, String password) { 16 checkSecurity(); 17 this.userManager.addUser(username,password); 18 } 19 20 @Override 21 public void deleteUser(int userid) { 22 checkSecurity(); 23 this.userManager.deleteUser(userid); 24 } 25 26 @Override 27 public void modifyUser(int userid, String username, String password) { 28 checkSecurity(); 29 this.userManager.modifyUser(userid,username,password); 30 } 31 32 @Override 33 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 @Override 22 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 @Override 33 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()----------