【概述】

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. HW5.13

    public class Solution { public static void main(String[] args) { System.out.printf("%s\t%s\n&qu ...

  2. 数据绑定之DataFormatString

    设定BoundField的DataFormatString,通常有以下几种 DataFormatString= "{0:C}" 货币,货币的格式取决于当前Thread中Cultur ...

  3. javascript函数的4种调用方式

    在javascript中一共有4种函数调用模式,分别是:方法调用模式.函数调用模式.构造函数调用模式和apply(call)调用模式,这4种模式的主要差异在于如何初始化关键参数this. 方法调用模式 ...

  4. 来自奢侈品行业的CEO能给苹果带来什么?

    重回苹果的奢侈品大佬:保罗丹诺威 作为伊夫·圣罗兰(Saint Laurent)时尚集团的前CEO,保罗丹诺威(Paul Deneve)9月将正式加入苹果公司,并负责该公司所谓的“特殊项目”,同时直接 ...

  5. ASP.NET MVC- Model- An Introduction to Entity Framework for Absolute Beginners

    Introduction This article introduces Entity Framework to absolute beginners. The article is meant fo ...

  6. 增强Eclipse ,MyEclipse 的代码自动提示功能

    一般默认情况下,Eclipse ,MyEclipse 的代码提示功能是比Microsoft Visual Studio的差很多的,主要是Eclipse ,MyEclipse本身有很多选项是默认关闭的, ...

  7. 六款值得推荐的android(安卓)开源框架简介【转】

    http://my.oschina.net/u/1244156/blog/380647 1.volley 项目地址 https://github.com/smanikandan14/Volley-de ...

  8. SilkTest天龙八部系列1-初始化和构造函数

    SilkTest没有提供专门的构造函数机制,但是在类对象生成的过程中,会先初始化在类中申明的变量.我们可以在初始化该变量的时, 调用某些函数完成对象初始化工作,看上去好像是调用了构造函数一样.不过要记 ...

  9. 线程间操作无效 progressBar2线程不能被访问

    出现这个问题解决的方法有两种第一种就是使用 // Form1.CheckForIllegalCrossThreadCalls = false;//不对跨线程的调用 使用这个的时候是判断线程是否运行正常 ...

  10. android 开发过程中碰到的 Failed to create the part's controls 问题

    在开发android的过程中,遇到一个很奇怪的问题,出现了“ Failed to create the part's controls” 的错误,查询了N多资料,然后逐条删除代码测试, 后来发现是变量 ...