【概述】

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. VMWare虚拟机USB连接问题

    错误31:连接到系统上的设备没有发挥作用 原文链接 描述 常用 VMware 虚拟机的有事应该遇到这种情况,就是装完 VMware ,启动时 VMware 下面会有个黄框中有" USB di ...

  2. Oracle ABP(Autotask Background Process)

    ABP相当于自动任务与调度程序之间的中介,其主要作用是将自动任务转换成Autotask作业,供调度程序执行.同样重要的是,ABP还维护所有任务执行的历史记录.ABP将其专用资料档案库存储在sysaux ...

  3. SQLite 入门教程(二)创建、修改、删除表 (转)

    转于 SQLite 入门教程(二)创建.修改.删除表 一.数据库定义语言 DDL 在关系型数据库中,数据库中的表 Table.视图 View.索引 Index.关系 Relationship 和触发器 ...

  4. Lucene子项目------------------Solr遇到的问题

    SolrCore Initialization Failures paper: org.apache.solr.common.SolrException:org.apache.solr.common. ...

  5. 一个不喜欢读书的Javaer的读书单

    很可惜,从我一开始学技术开始,我就不喜欢看书,严重的时候翻不到两页就会开始狂打瞌睡.很幸运,有互联网能够为我提供很多知识,甚至一些知识从网上看来的会更加权威一些.但是,我的经验告诉我,无论是从功利性的 ...

  6. C#中多线程 委托的使用

    背景:  什么是多线程?我们在建立以个C#项目时,往往会在Form1上添加控件,然后写代码,初 学者都是在重复这个过程,其实这个过程是单线程的,可以理解为只有“main”主线程,有 的时候往往需要同时 ...

  7. android 的异步任务

    /** * 异步任务的三个泛型参数: * 1.调用execute方法时传入的参数类型,输入参数 * 2.progressUpdate的方法入参 * 3.异步任务的返回结果类型 doInBackgrou ...

  8. Day07 - Python 网络编程 Socket

    1. Python 网络编程 Python 提供了两个级别访问网络服务: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口 ...

  9. Android_EditText

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...

  10. 一种通用数据采集的schema定义形式

    { "name": "凤凰金融", "notice": { "data": "attribute", ...