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)方法,调用目标方法。

 

posted @ 2016-06-14 02:12  HigginCui  阅读(347)  评论(0编辑  收藏  举报