zoukankan      html  css  js  c++  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     @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()----------

    
    
    
  • 相关阅读:
    在springboot程序中自定义注解和反序列化实现
    文章相似度算法调研
    HTTP协议详解
    prototype.js 让你更深入的了解javascript的面向对象特性(转)
    ajax框架汇总
    prototype源码分析(转)
    c#中静态成员和实例成员(转)
    .NET中IDisposable接口的基本使用 (转)
    sql server 数据库优化(转)
    ADO.NET事物
  • 原文地址:https://www.cnblogs.com/zhongzhongdebokeyuan/p/5822100.html
Copyright © 2011-2022 走看看