zoukankan      html  css  js  c++  java
  • 17_AOP入门准备_Salay案例(利用动态代理)

    【概述】

    JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。

      InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态地将横切逻辑和业务逻辑编织在一起。

      Proxy利用InvocationHandler动态地创建一个符合某一接口的实例,生成目标类的代理对象。

    【案例分析】

    查看Salary:

      1.启动日志

      2.启动安全性的框架

      3.检查权限:如果有查看工资的权限,则查看工资,否则提示"权限不足"

    【工厂截图】

    【SalaryManager.java】

    package com.HigginCui.proxy.salary;
    
    //目标接口
    public interface SalaryManager {
        //查看工资
        public void showSalary();
    }

    【SalaryManagerImpl.java】

    package com.HigginCui.proxy.salary;
    //目标类
    public class SalaryManagerImpl implements SalaryManager{
        @Override
        public void showSalary() {
            System.out.println("Show Salary...");
        }
    }

    【Logger.java】

    package com.HigginCui.proxy.salary;
    //日志类
    public class Logger {
        public void logging(){
            System.out.println("logging ...");
        }
    }

    【Privilege.java】

    package com.HigginCui.proxy.salary;
    //权限类
    public class Privilege {
        private String access;
        public String getAccess() {
            return access;
        }
        public void setAccess(String access) {
            this.access = access;
        }
    }

    【Security.java】

    package com.HigginCui.proxy.salary;
    //安全性框架类
    public class Security {
        public void security(){
            System.out.println("security ...");
        }
    }

    【SalaryManagerInterceptor.java】

    package com.HigginCui.proxy.salary;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    //拦截器
    public class SalaryManagerInterceptor implements InvocationHandler{
        private Object target;
        private Logger logger;
        private Security security;
        private Privilege privilege;
        
      /**
       * target:希望被代理的目标对象
       */
    public SalaryManagerInterceptor(Object target,Logger logger,Security security,Privilege privilege){ this.target=target; this.logger=logger; this.security=security; this.privilege=privilege; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //1.开启日志 this.logger.logging(); //2.开启安全性框架类 this.security.security(); //3.检查权限,如果是"admin",则允许查看,否则提示"权限不足" if(this.privilege.getAccess().equals("admin")){ //4.调用目标方法 method.invoke(target, args); //通过java反射间接调用目标对象的方法 }else{ System.out.println("权限不足..."); } return null; } }

     【SalaryTest.java】

    package com.HigginCui.test;
    
    import java.lang.reflect.Proxy;
    
    import org.junit.Test;
    
    import com.HigginCui.proxy.salary.Logger;
    import com.HigginCui.proxy.salary.Privilege;
    import com.HigginCui.proxy.salary.SalaryManager;
    import com.HigginCui.proxy.salary.SalaryManagerImpl;
    import com.HigginCui.proxy.salary.SalaryManagerInterceptor;
    import com.HigginCui.proxy.salary.Security;
    //模拟客户端
    public class SalaryTest {
        @Test
        public void testSalart(){
            Object target=new SalaryManagerImpl();  //希望被代理的目标对象
            Logger logger =new  Logger();
            Security security=new Security();
            Privilege privilege=new Privilege();
            /*
             * 如果是"admin",提示"Show Salary..."
             * 否则,提示"权限不足"
             */
            privilege.setAccess("admin");
         //将目标业务对象target和横切代码编织到一起 SalaryManagerInterceptor interceptor
    =new SalaryManagerInterceptor(target, logger, security, privilege); /**
         * 第1个参数:目标对象target的类加载器
         * 第2个参数:目标对象target的需要实现的接口
         * 第3个参数:整合了目标对象的和横切代码的编织器对象interceptor
         */
         SalaryManager proxy
    =(SalaryManager) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor); proxy.showSalary(); } }

    【运行结果】

    logging ...
    security ...
    Show Salary...

    【分析】

    (1)关于InvocationHandler接口

    [ invoke(Object proxy,Method method,Object[] args)方法 ]

      proxy:  最终生成的代理对象,一般不会用到

    method: 被代理目标实例的某个具体方法,通过它可以发起目标实例方法的反射调用

         args: 通过被代理的实例的方法的参数,在方法反射调用时使用。

    [ 构造方法 ]

    构造方法中通过target传入希望被代理的目标对象。

    在例子中的接口方法invoke(Object proxy,Method method,Object[] args)方法中,将目标实例传递给method.invoke(target,args)方法,调用目标方法。

  • 相关阅读:
    Python并发(一)
    Python协程详解(二)
    Python协程详解(一)
    Python装饰器
    ●BZOJ 3676 [Apio2014]回文串
    ●POJ 3974 Palindrome(Manacher)
    ●BZOJ 1692 [Usaco2007 Dec]队列变换
    ●BZOJ 4698 Sdoi2008 Sandy的卡片
    ●BZOJ 4516 [Sdoi2016]生成魔咒
    ●BZOJ 3238 [Ahoi2013]差异
  • 原文地址:https://www.cnblogs.com/HigginCui/p/5582617.html
Copyright © 2011-2022 走看看