技术标签: spring proxy aop java 设计模式
为了让博客内容看着舒服一些,所以我把静态代理和动态代理的代码在最后了哦!
什么是代理?
静态代理:
由程序创建或特定工具自动生成源代码,在程序运行前,代理类的.class文件就已经存在。
动态代理:
在程序运行时,运用反射机制动态创建而成,无需手动编写代码。
什么是静态代理?
优点:
缺点:
动态代理:
两种动态代理的区别:
Spring AOP中的代理使⽤的默认策略:
首先在项目中新建一个代理的包,包名为 proxy,
还记得文章开头的ABC吗?
A ->B-> C (A类是调用方法的类,B类就是代理,C类是真正的方法)
A:ProxyTest:调用方法的类
B:StaticProxyPayServiceImpl(静态代理)、JdkProxy(JDK动态代理)、CglibProxy(CGLib动态代理)
C:PayServiceImpl:真正的方法
PayService:该demo要实现的接口
结构如下:
该demo要实现的接口 – PayService:
public interface PayService {
String callback(String outTradeNo);
int save(int userId, int productId);
}
真正的方法 --PayServiceImpl:
public class PayServiceImpl implements PayService{
public String callback(String outTradeNo) {
System.out.println("PayServiceImpl 回调 方法 callback");
return outTradeNo;
}
public int save(int userId, int productId) {
System.out.println("PayServiceImpl 回调 方法 save");
return productId;
}
}
代理模块代码:
public class StaticProxyPayServiceImpl implements PayService{
private PayService payService;
//通过构造函数的方式注入
public StaticProxyPayServiceImpl(PayService payService){
this.payService = payService;
}
public String callback(String outTradeNo) {
System.out.println("StaticProxyPayServiceImpl callback begin");
String result = payService.callback(outTradeNo);
System.out.println("StaticProxyPayServiceImpl callback end");
return result;
}
public int save(int userId, int productId) {
System.out.println("StaticProxyPayServiceImpl save begin");
int id = payService.save(userId, productId);
System.out.println("StaticProxyPayServiceImpl save end");
return id;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxy implements InvocationHandler {
//目标类
private Object targetObject;
//获取代理对象
public Object newProxyInstance(Object targetObject){
this.targetObject = targetObject;
//绑定关系,也就是和具体的哪个实现类关联
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}
//Object proxy:被代理的对象
//Method method:要调⽤的⽅法
//Object[] args:⽅法调⽤时所需要参数
public Object invoke(Object proxy, Method method, Object[] args) {
Object result = null;
try {
System.out.println("通过JDK动态代理调用"+method.getName()+",打印日志 begin");
result = method.invoke(targetObject,args);
System.out.println("通过JDK动态代理调用"+method.getName()+",打印日志 end");
} catch (Exception e){
e.printStackTrace();
}
return result;
}
}
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
//目标类
private Object targetObject;
//绑定关系
public Object newProxyInstance(Object targetObject){
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
//设置代理类的⽗类(⽬标类)
enhancer.setSuperclass(this.targetObject.getClass());
//设置回调函数
enhancer.setCallback(this);
//创建⼦类(代理对象)
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object result = null;
try {
System.out.println("通过CGLIB动态代理调用"+method.getName()+",打印日志 begin");
result = methodProxy.invokeSuper(o,args);
System.out.println("通过CGLIB动态代理调用"+method.getName()+",打印日志 end");
} catch (Exception e){
e.printStackTrace();
}
return result;
}
}
想测试哪个,就把哪个的代码打开,这里只打开了CGLib代理的测试!
public class ProxyTest {
public static void main(String[] args) {
//正常调用
// PayService payService = new PayServiceImpl();
// payService.callback("fdvwtr");
//使用代理调用
// PayService payService = new StaticProxyPayServiceImpl(new PayServiceImpl());
// payService.save(123, 654);
// payService.callback("fdvwtr");
//JDK动态代理
// JdkProxy jdkProxy = new JdkProxy();
// //获取代理类对象
// PayService payServiceProxy = (PayService) jdkProxy.newProxyInstance(new PayServiceImpl());
// //调用目标方法
// payServiceProxy.callback("151sfds");
// payServiceProxy.save(1212,5656);
//CGLiB动态代理
CglibProxy cglibProxy = new CglibProxy();
PayService payService = (PayService)cglibProxy.newProxyInstance(new PayServiceImpl());
payService.callback("dsfasfasd");
payService.save(555,666);
}
}
文章浏览阅读7.5k次。原因:这是由于系统默认会查找/usr/bin下的命令,如果这个命令不在这个目录下,当然就找不到命令解决方法:我们需要做的就是映射一个链接到/usr/bin目录下,相当于建立一个链接文件。1. 知道mysql命令或mysqladmin命令的完整路径,比如mysql的路径是:/usr/local/mysql/bin/mysql,2. 执行命令:$sudo ln -s /usr/lo_在terminal内输入mysql -u root -p,提示“comman not found”.
文章浏览阅读888次,点赞18次,收藏18次。1.背景介绍差分进化算法(Differential Evolution, DE)是一种基于变异和重组的全局搜索优化算法,它在过去几年中得到了广泛的关注和应用。在这篇文章中,我们将深入探讨差分进化算法与多对象优化问题的研究进展,包括背景介绍、核心概念与联系、算法原理和具体操作步骤、数学模型公式详细讲解、具体代码实例和解释、未来发展趋势与挑战以及常见问题与解答。1.1 背景介绍多对象优化问...
文章浏览阅读456次。小程序毕设作品之微信预约订座小程序毕业设计(7)中期检查报告
文章浏览阅读1.5k次,点赞5次,收藏11次。C语言命令编程按下Win+R,输入CMD,进入命令行模式Ipconfig是查看本机的ip.Ping www.qq.com是查看网络是否畅通这个时候是文件被占用,退出这个应用程序就可以CD是进入一个文件夹的路径,进入路径以后,就可以直接执行System在stdlib.h中system(“C:\CMD.exe”);参数只有一个,就是输入命令行并执行所有的C程序,只要是黑窗口,都可以在命令行下执行,C黑窗口程序可以调用其他任何C语言黑窗口程序在命令行执行,调_c语言 运行 命令行
文章浏览阅读1.5w次,点赞32次,收藏253次。目录前言一、什么是神经网络?二、手写代码1.主代码2.归一化函数2.反归一化函数二、工具箱代码总结前言因为项目需要,自己搞了一个BP神经网络的程序,顺便做一下笔记人工智能现在的分支有1机器学习:就是通过算法从大数据中学习到规律,而后对未知的结果进行预测。 1.21监督学习:输入和输出已知,训练集中的目标是人为注入的,常见的作用是分类数据。回归分析,统计分类。 1.22非监督学习:事先没有样本,直接对数据进行建模,非监督学习最点..._编写 1 套相关的神经网络应用系统程序matlab
文章浏览阅读38次。ubuntu
文章浏览阅读1w次。看了帖子上有很多关于H5调用手机摄像头、相册的例子,也有很多可靠的栗子,综合技术点针对HTML5调用用手机相机、相册的的一次代码整合。实现提供完成的Demo提供给大家,可直接应用于项目中需要图片上传的功能。因为是H5直接调用,并没有用到像Cordova或者HTML5Plus的 JavaScript库去调用手机硬件,因此在低端手机可能会调用不到摄像图、或者相册,因此这也是在H5在这里的不足,不好解决。_h5实现调用手机摄像头相册。完美实现图片压缩、预览、删除的功能。---demo
文章浏览阅读449次。VMware vFlash Read Cache allowsto leverage host local SSDs enabling a caching layer for the VMs. No other software or extra VIBs need to be installed on the host since allneces..._vmware读取外设flash
文章浏览阅读1.7k次。android笔记链接_安卓 笔记软件 超链接
文章浏览阅读487次。也许是自己太笨,搞了一天用u盘安装都是重启后没有启动项,在网上找了很多的解决方法都无效,我认为肯定是启动项被写进了u盘里,所以重启才没有启动项,最终决定放弃,改用硬盘安装;将安装步骤记下来备忘 先准备两个东西EasyBCD软件和iso镜像1.安装EasyBCD_ubuntu自定义硬盘安装
文章浏览阅读6.4k次。java 切割字符串split用法_list.add(ss.substring(start,i));
文章浏览阅读498次。Problem: Fill the Square Description: 有一个矩阵,当中的元素是大写字母,但是有个前提,相邻的位置大写字母不能相同,现在这个矩阵中的某些位置已近有字母了,要你把这个矩阵填满,并且保证字典序最小。 Solution: 简单DFSDFS。但是要注意的是,如果我这种做法超时了,那就把空的位置存到一个数组中,这样dfsdfs时就可以减少栈的空间使用。 Code(JA_uva11520