Java动态代理的两种实现方式:
方式一:传统的代理
package cn.hc.domain; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* 代理对象创建的工厂类
* @author hc
*
*/
public class JDKProxyFactory implements InvocationHandler{
//被代理对象
private Object target;
public JDKProxyFactory(Object target){
this.target=target;
}
//创建代理
public Object createProxy(){
//三个参数:类加载器 实现接口 invocationHandler
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
// TODO Auto-generated method stub
//调用目标真是的方法
System.out.println("日志已经被记录");
return arg1.invoke(target, arg2);
}
}
此种方法的缺陷在于:被代理的类必须实现接口
package cn.hc.domain;
//代理对象的接口
public interface UserDao {
public void save();
public void update();
}package cn.hc.domain;
/**
* 被代理的目标对象
* @author hc
*
*/
public class UserDaoImpl implements UserDao { public void save() {
// TODO Auto-generated method stub
System.out.println("添加用户");
} public void update() {
// TODO Auto-generated method stub
System.out.println("更新用户");
} }
//测试类package cn.hc.domain; import org.junit.Test; public class TestProxy {
@Test
public void testJdkProxy(){
//测试jdk动态代理
//1真实目标对象
UserDao userDao=new UserDaoImpl();
//System.out.println(userDao);
UserDao proxy=(UserDao) new JDKProxyFactory(userDao).createProxy();
proxy.save();
proxy.update();
}
}
测试结果:
日志已经被记录
添加用户
日志已经被记录
更新用户
方式2:cglib动态代理
package cn.hc.cglibProxy; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; public class CGlibProxyFactory implements MethodInterceptor{
private Object target;
public CGlibProxyFactory(Object target){
this.target=target;
}
//创建代理对象的方法
public Object createProxy() {
//创建Enhance对象
Enhancer enhancer=new Enhancer();
//cglib创建代理,对目标对象创建子类对象
enhancer.setSuperclass(target.getClass());
//传入callback对象,对目标增强
enhancer.setCallback(this);
return enhancer.create();
}
//arg3 用于执行父类的方法
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
// TODO Auto-generated method stub
System.out.println("开始记录日志");
return arg1.invoke(target,arg2);
}
}
package cn.hc.cglibProxy;
public class ProductDao {
public void add(){
System.out.println("添加");
}
public void delete(){
System.out.println("删除");
}
}
//测试方法
package cn.hc.cglibProxy;
import org.junit.Test;
public class CGlibTest {
@Test
public void test1(){
//创建目标对象
ProductDao dao=new ProductDao();
ProductDao proxy=(ProductDao) new CGlibProxyFactory(dao).createProxy();
proxy.add();
proxy.delete();
}
}
Java动态代理的两种实现方式:的更多相关文章
- 动态代理的两种实现方式(JDK/Cglib)
=========================================== 原文链接: 动态代理的两种实现方式(JDK/Cglib) 转载请注明出处! ================== ...
- java动态代理的两种方法
动态代理,有两种情况,第一种是有接口的情况下,你可以选择为jdk自带的动态代理的方式来编写程序,但你想要为一个实在的类编写动态代理的方式的话,这时候就必须选择一些开源的lib包,如cglib包,同时还 ...
- java动态代理的2种实现方式
java的动态代理在接java的api上有说明,这里就不写了.我理解的代理: 对特定接口中特定方法的功能进行扩展,这就是代理.代理是通过代理实例关联的调用处理程序对象调用方法. 下面通过一个例子看一下 ...
- Java动态代理的两种实现方法
注:文章转载自:https://blog.csdn.net/m0_38039437/article/details/77970633 一.代理的概念 动态代理技术是整个java技术中最重要的一个技术, ...
- Java中String对象两种赋值方式的区别
本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过“字面量”赋值 ...
- 细说java中Map的两种迭代方式
曾经对java中迭代方式总是迷迷糊糊的,今天总算弄懂了.特意的总结了一下.基本是算是理解透彻了. 1.再说Map之前先说下Iterator: Iterator主要用于遍历(即迭代訪问)Collecti ...
- 动态代理的两种方式,以及区别(静态代理、JDK与CGLIB动态代理、AOP+IoC)
Spring学习总结(二)——静态代理.JDK与CGLIB动态代理.AOP+IoC 目录 一.为什么需要代理模式 二.静态代理 三.动态代理,使用JDK内置的Proxy实现 四.动态代理,使用cg ...
- Java中容器的两种初始化方式比较
List,Set,Map的两种初始化赋值方式 List List<Integer> list2 = new ArrayList<Integer>(); for (int i= ...
- Java实现动态代理的两种方式
http://m.blog.csdn.net/article/details?id=49738887
随机推荐
- Layer弹窗组件
layer是一款近年来备受青睐的web弹层组件,她具备全方位的解决方案,致力于服务各水平段的开发人员,您的页面会轻松地拥有丰富友好的操作体验. Layer的开发手册和下载地址 http://layer ...
- viewPager的基本使用
viewPager是android扩展包v4中的类,这个类可以使用户左右切换当前的view. 特性: 1.viewPager直接继承了viewGroup类,所以它是一个容器类,可以在其中添加其它的vi ...
- C# 常用类
一.Convert 主要用于数据类型的转换,常用的静态方法有: Convert.ToSingle():把数据转换为单精度浮点数,参数常为字符串 Convert.ToDouble():转为双精度浮点数 ...
- win7安装virtualbox遇到的问题
今天用台式机的时候想装个virtualbox跑centos做测试用,结果centos始终装不上,vbox一直提示无法开启任务.重装vbox,以及手动点击安装xxx.inf文件,都不行. 以前用的win ...
- fopen w c
http://php.net/manual/en/function.fopen.php
- ArcGIS Server GP服务发布与测试(基础版)
版本:ArcGIS Server 10.4 环境:win10 测试目标:创建一个GP服务,功能为根据要素属性信息(如FID)选择出输入内容的对应匹配要素. 注:这个测试非常基础,仅供新手发布GP ...
- 改变UIButton 图片和文字的位置
//设置字体和图片之间的间距 _btnLeft.titleEdgeInsets = UIEdgeInsetsMake(0, -_btnLeft.imageView.frame.size.width, ...
- Convert and Cast for Date and Money format.
SELECT REPLACE(REPLACE(@str, CHAR(13), ''), CHAR(10), '') The below script removes the TAB(Horozonta ...
- iOS: 上传App到AppStore,由于Xcode上传太慢,换成Application Loader上传,速度秒传
一.遇到的遭遇 在之前的项目开发中,本人有点固执,一直采用xcode打包后再上传,结果可想而知: (1)要么上传时速度慢的跟蜗牛似的,等的我心力交瘁(不排除网络不给力的原因,公司这个吊问题快把我气疯了 ...
- Oracle 触发器的简单命令
-- 创建触发器的基本命令 create or replace trigger td after delete on ss begin dbms_output.put_line('删除成功'); en ...