【概述】

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

17_AOP入门准备_Salay案例(利用动态代理)的更多相关文章

  1. 关于利用动态代理手写数据库连接池的异常 java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to java.sql.Connection

    代码如下: final Connection conn=pool.remove(0); //利用动态代理改造close方法 Connection proxy= (Connection) Proxy.n ...

  2. 动态代理案例1:运用Proxy动态代理来增强方法

    动态代理案例1: /*要求:运用Proxy动态代理来增强方法 题目:    1.定义接口Fruit,其中有addFruit方法    2.定义实现类FruitImpl,实现Fruit接口    3.定 ...

  3. 【Java入门提高篇】Day11 Java代理——JDK动态代理

    今天来看看Java的另一种代理方式--JDK动态代理 我们之前所介绍的代理方式叫静态代理,也就是静态的生成代理对象,而动态代理则是在运行时创建代理对象.动态代理有更强大的拦截请求功能,因为可以获得类的 ...

  4. 【原创】JDK动态代理,此次之后,永生难忘。

    动态代理,这个词在Java的世界里面经常被提起,尤其是对于部分(这里强调“部分”二字,因为有做了一两年就成大神的,实力强的令人发指,这类人无疑是非常懂动态代理这点小伎俩的)做了一两年新人来说,总是摸不 ...

  5. Java编程的逻辑 (86) - 动态代理

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  6. Proxy 代理模式 动态代理 cglib MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. JDK动态代理,此次之后,永生难忘

    出自:http://www.cnblogs.com/dreamroute/p/5273888.html#3839242 首先感谢"神一样的存在"的文章! 动态代理,这个词在Java ...

  8. SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架

    1 JDK动态代理详解 静态代理.JDK动态代理.Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文. 1.1 JDK代理的基本步骤 >通过实现InvocationHandler接口来 ...

  9. 动态代理在WEB与JDBC开发中的应用

    WEB案例 目前有一个2005年开始,基于Struts1的Web项目A,其验证部分依赖于主站的SSO(单点登录).在请求站点A的时候,用户会被强制带去做SSO验证,通过身份验证后后,主站会自动地把请求 ...

随机推荐

  1. C#调用VC DLL堆栈不对称

    今天在调程序时,C#调用VC 编译的dll出现堆栈不对称,查了一下资料,转载在这里供大家参考. 问题描述:对 PInvoke 函数“xxFunction()”的调用导致堆栈不对称.原因可能是托管的 P ...

  2. java操作pdf添加页眉条码添加水印图片

    添加条码页眉以及图片水印 1. 引入jar包     1. itext-4.2.1.jar     2. itext-asian-5.2.0.jar     3. jbarcode-0.2.8.jar ...

  3. HW1.2

    public class Solution { public static void main(String[] args) { System.out.println("Welcome to ...

  4. POJ1182食物链 (并查集)

    第一反应就是和那个搞基的虫子的题很像(poj2492 http://www.cnblogs.com/wenruo/p/4658874.html),不过是把种类从2变成了3. 错在很白痴的地方,卡了好久 ...

  5. 关于学习Scala语言的一些感悟

    进入话题! 我们知道哈,Spark源码采用Scala语言编写,那么阅读Spark源码之前,是否一定先学Scala呢? 我个人认为,不必,只要我们有一些java或c++编写语言的基础,就可以看Spaar ...

  6. hdoj 1898 Sempr == The Best Problem Solver?

    Sempr == The Best Problem Solver? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/3276 ...

  7. 开发日志_Jan.8.2017

    这两天继续着手开发碰撞部分. 主要工作是写碰撞类和运动线程类.碰撞主要在于算法,运动线程只要管理好就行了. 之前碰撞测试中(即还未添加完整碰撞算法时)遇到各种bug,疑似机器人和小球的定位点不明所造成 ...

  8. DevExpress GridControl GridView 导出到 Excel 类

    说明: 1>GridView 导出到 Excel (如果分页,只导出当前页数据) 2>GridView 导出到 Excel 3>方法2可以参考DataTable 导出到 Excel ...

  9. 【转】C++中了类继承和调用父类的构造函数方法

    构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法).因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需 ...

  10. RHCA442学习笔记-Unit13网络性能调整

    UNIT 13 Essential Network Tuning 网络性能调整        目标:1. 应用队列技术最大化网络吞吐量            2. 调整TCP和non-TCP网络soc ...