AOP基础-JDK动态代理
动态代理技术就是用来产生一个目标对象的代理对象的,代理对象应与目标对象(被代理的对象)有相同的方法,实现对目标对象访问的拦截,并增强目标对象的一些功能,而不需要目标对象去做任何的更改,使得目标对象有更加纯粹的业务逻辑。不多解释,上代码。
需求:在一个业务模块方法中添加日志。
一、常规的写法
1.1、接口Animals
package com.duchong.proxy_test; /**
* @author DUCHONG
* @since 2017-12-28 9:10
**/
public interface Animals {
/**
* 吃
* @param name
* @return
*/
String eat(String name); /**
* 吠
* @param name
* @return
*/
String bark(String name); /**
* 跑
* @param name
* @return
*/
String move(String name);
}
1.2、接口的实现类Dog
package com.duchong.proxy_test; /**
* @author DUCHONG
* @since 2017-12-28 9:21
**/
public class Dog implements Animals { @Override
public String eat(String name) {
System.out.println("Dog eat method start.....");
return "dog eat "+name;
} @Override
public String move(String name) {
System.out.println("Dog move method start.....");
return "dog move "+name;
} @Override
public String bark(String name) {
System.out.println("Dog bark method start.....");
return "dog bark "+name;
} public static void main(String[] args) {
Dog dog=new Dog();
System.out.println(dog.eat("Bone"));
System.out.println(dog.move("Faster"));
System.out.println(dog.bark("Wang Wang Wang"));
}
}
1.3、输出

以上写法,能实现要求,但是缺点是,像日志这种非业务逻辑相关的代码混在里面,看起来混乱,不易维护,而且这些代码块大多类似,对于这样的代码块,我们都知道,是可以抽取出来的,定义公共功能,这样就使得业务模块更简洁, 只包含核心业务代码。
二、基于动态代理的写法
2.1、接口的实现类Dog
package com.duchong.proxy_test; /**
* @author DUCHONG
* @since 2017-12-28 9:21
**/
public class Dog implements Animals {
@Override
public String eat(String name) {
return "dog eat "+name;
} @Override
public String move(String name) {
return "dog move "+name;
} @Override
public String bark(String name) {
return "dog bark "+name;
} }
2.2、使用java.lang.reflect.Proxy动态代理实现,即提取目标对象的接口(或者说JDK生成代理必须使用接口),然后对接口创建代理.
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
使用Proxy.newProxyInstance方法就可以返回一个代理对象,这个方法总共有3个参数
- ClassLoader loader 生成代理对象使用哪个类装载器加载
- Class<?>[] interfaces 生成哪个对象的代理对象,通过接口指定,或者说代理要实现的接口
- InvocationHandler h 产生的这个代理对象要做什么,这个接口里面只有一个方法,可以使用一个匿名内部类来实现
2.3、代理类
package com.duchong.proxy_test; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* dog代理类
*
* @author DUCHONG
* @since 2017-12-28 10:17
**/
public class DogProxy{ //需要被代理的目标对象
private Animals target; public DogProxy(Animals target){
this.target=target;
} /**
* 返回基于接口创建的代理
* @return
*/
public Animals getDogProxy(){ return (Animals) Proxy.newProxyInstance(DogProxy.class.getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("eat")){
System.out.println("Dog eat method start.....");
return method.invoke(target,args);
}
else if(method.getName().equals("move")){
System.out.println("Dog move method start.....");
return method.invoke(target,args);
}
else if(method.getName().equals("bark")){
System.out.println("Dog bark method start.....");
return method.invoke(target,args);
}
else{
return null;
}
}
}); } }
2.4、Main运行
package com.duchong.proxy_test;
/**
* @author DUCHONG
* @since 2017-12-28 10:35
**/
public class Main {
public static void main(String[] args) {
//目标对象
Animals animals=new Dog();
//获得代理对象
Animals dog= new DogProxy(animals).getDogProxy();
//调用代理对象的方法
System.out.println(dog.eat("Bone"));
System.out.println(dog.move("Faster"));
System.out.println(dog.bark("Wang Wang Wang"));
}
}
2.5、输出

2.6、InvocationHandler原理
如果Proxy生成代理对象的时候,指定了InvocationHandler,那么用户调用代理对象的任何方法,该方法都是调用InvocationHandler的invoke方法,而Method就是当前调用的那个方法,通过getName 即可获取当前被调用方法的名称,从而在invoke被调用之前,添加日志等处理,而invoke方法被调用是需要两个参数,一个是调用改方法的对象,一个是该方法的参数,即为代码中的target和args.
AOP基础-JDK动态代理的更多相关文章
- Java基础-jdk动态代理与cglib动态代理区别
JDK动态代理 此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑. 代理模式在实际使用时需要指定具体的目标对象 ...
- spring---aop(2)---Spring AOP的JDK动态代理
写在前面 spring 事务是springAOP 的一个实现.我们以分析spring的事务,来分析spring的AOP实现. 基本知识 如果目标方法被spring的事务声明,则执行该目标方法的对象就会 ...
- Java基础-JDK动态代理
JDK的动态代理依靠接口实现 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代 ...
- (转)细说JDK动态代理的实现原理
原文:http://blog.csdn.net/mhmyqn/article/details/48474815 关于JDK的动态代理,最为人熟知的可能要数Spring AOP的实现,默认情况下,Spr ...
- spring---aop(4)---Spring AOP的CGLIB动态代理
写在前面 前面介绍了Spring AOP的JDK动态代理的过程,这一篇文章就要介绍下Spring AOP的Cglib代理过程. CGLib全称为Code Generation Library,是一个强 ...
- Spring Boot实践——Spring AOP实现之动态代理
Spring AOP 介绍 AOP的介绍可以查看 Spring Boot实践——AOP实现 与AspectJ的静态代理不同,Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改 ...
- AOP-底层原理(JDK动态代理实现)
AOP(JDK动态代理) 1,使用JDK动态代理,使用Proxy类里面的方法创建代理对象 (1)调用 newProxyInstance 方法 方法有三个参数 第一参数,类加载器 第二参数,增强方法所在 ...
- 【spring基础】AOP概念与动态代理详解
一.代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一 ...
- AOP的底层实现-CGLIB动态代理和JDK动态代理
AOP是目前Spring框架中的核心之一,在应用中具有非常重要的作用,也是Spring其他组件的基础.它是一种面向切面编程的思想.关于AOP的基础知识,相信多数童鞋都已经了如指掌,我们就略过这部分,来 ...
随机推荐
- java对象流(二)
对象流,可以将java中的对象转为字节进行输出.将对象写入文件时.文件输出流是将字节写入到文件中. 对象流是将给定的对象转化为一组字节.writeObject()方法就是将对象转为字节. 对象流,读的 ...
- FilterDispatcher处理流程
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 前身是:org.apache.struts2.dispatc ...
- Unity3D-UGUI图集打包与动态使用(TexturePacker)
参考地址: http://blog.csdn.net/cjsen/article/details/52487706 今天做项目大佬看我在做图集,就跟我说可以用工具打包图集,也就是TexturePack ...
- 2016-02-20WebForm登陆验证,判断用户是否登陆 PageBase类
http://blog.csdn.net/fanbin168/article/details/49404233 很多时候,WebFrom页面,我们需要判断用户是否已经登陆了.假如有很多页面,难道我们要 ...
- 【VS外接程序】利用T4模板生成模块代码
引言 记得第一次做asp.net mvc项目时,可以用model直接生成Html的增删改查页面, 没什么特殊要求都可以不用修改直接用了, 觉得很神奇,效率太高了.后来在做客户端开发时,发现很多模块都是 ...
- 分布式_理论_08_Consistent Hash(一致性哈希算法)
一.前言 五.参考资料 1.分布式理论(八)—— Consistent Hash(一致性哈希算法)
- MySQL管理
http://www.yiibai.com/mysql/administration.html 在本节中,您将学习有关MySQL管理教程,包括MySQL服务器启动和关闭,MySQL服务器安全性,MyS ...
- skynet源码阅读<5>--协程调度模型
注:为方便理解,本文贴出的代码部分经过了缩减或展开,与实际skynet代码可能会有所出入. 作为一个skynet actor,在启动脚本被加载的过程中,总是要调用skynet.start和sky ...
- 7.MySQL优化---存储过程和存储函数
转自互联网. 当一个大型系统在建立时,会发现,很多的SQL操作是有重叠的,个别计算是相同的,比如:业务系统中,计算一张工单的计算方式.当遇到这些情况时,我们运用存储过程就是一个非常棒的优化啦.那么,什 ...
- PHP Smarty无法解析模板文件
/****************************************************************************** * PHP Smarty无法解析模板文件 ...