动态JDK代理方式-实现类增强
需求描述:
抽取dao层开启和提交事物交由代理类一并执行
分析:
假如UserDao接口中有很多方法,例如addUser()、deleteUser()、updateUser()等等,需要频繁的和数据库打交道,必然在每个方法里都会有开启事物,提交事务的操作。如果把开启事物和提交事物写在一个类A中不同方法中,由一个工厂将dao层和A类进行整合,得到一个代理的UserDao的实现对象,它即有原UserDao实现类中的各个方法,又有A类中的事物方法。即可实现切面管理事物。
代码:
UserDao接口:
package com.xx.dao;
public interface UserDao {
//增
void addUser();
//删
void deleteUser();
//改
void updateUser();
}
UserDaoImpl实现类:
package com.xx.dao;
public class UserDaoImpl implements UserDao{
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
@Override
public void updateUser() {
System.out.println("更新用户");
}
}
切面类:
package com.xx.dao;
public class MyAspect {
public void before(){
System.out.println("开启事物");
}
public void after(){
System.out.println("关闭事物");
}
}
代理工厂类:
package com.xx.dao;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 代理工厂(代理UserDao生成特定功能的实现类对象)
* @author phoebe
*
*/
public class ProxyFactory {
//被代理类
private static UserDao userDao = new UserDaoImpl();
//切面类
private static MyAspect myAspect = new MyAspect();
/* 获取新的代理类
* loader:类加载器(选当前类的类加载器)
* 方法一:当前类.class.getClassLoader();
* 方法二:对象.getClass.getClassLoader();
* interfaces:代理生成的对象是哪个接口的实现类呢?
* 方法一:new Class[]{接口.class}
* 方法二:对象.getClass().getInterfaces(),此仅能返回当前对象实现类的接口,并不能返回其父接口
* InvocationHandler:使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的 Proxy 实例。
*/
public static UserDao createProxyUserService(){
UserDao proxyInstance = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object object = null;
//可以通过method.getName()控制是否增强
if(!("updateUser".equals(method.getName()))){
myAspect.before();
object = method.invoke(userDao, args);
myAspect.after();
System.out.println(object+"为什么是null?尚未知晓");
return object;
}
System.out.println(object+"为什么是null?尚未知晓");
return object;
}
});
//返回UserDao的新实例对象
return proxyInstance;
}
}
测试类:
package com.xx.action;
import com.xx.dao.ProxyFactory;
import com.xx.dao.UserDao;
public class TestProxy {
public static void main(String[] args) {
UserDao userService = ProxyFactory.createUserService();
userService.addUser();
userService.deleteUser();
userService.updateUser();
}
}
效果:
开启事物
-------添加用户-------
关闭事物
null为什么是null?尚未知晓
开启事物
-------删除用户-------
关闭事物
null为什么是null?尚未知晓
null为什么是null?尚未知晓
动态JDK代理方式-实现类增强的更多相关文章
- 面向切面编程之手动JDK代理方式
需求描述: 抽取dao层开启和提交事物交由代理类一并执行 分析: 假如UserDao接口中有很多方法,例如addUser().deleteUser().updateUser()等等,需要频繁的和数据库 ...
- Java代理(静态/动态 JDK,cglib)
Java的代理模式是应用非常广泛的设计模式之一,也叫作委托模式,其目的就是为其他的对象提供一个代理以控制对某个对象的访问和使用,代理类负责为委托类预处理消息,过滤消息并转发消息,以及对消息执行后续处理 ...
- 面经手册 · 第13篇《除了JDK、CGLIB,还有3种类代理方式?面试又卡住!》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 编程学习,先铺宽度还是挖深度? 其实技术宽度与技术深度是相辅相成的,你能了解多少技术 ...
- 面向切面编程之cglib代理方式
思想: 和上一篇面向切面编程之手动JDK代理方式上的需求和开发模式一样.不同的是目标类没有接口,只有实现类,采用的是spring中提供的Enhancer类继承目标类实现的代理方式. 需要导入的jar包 ...
- Spring的两种代理方式:JDK动态代理和CGLIB动态代理
代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对 ...
- Jmh测试JDK,CGLIB,JAVASSIST动态代理方式的性能
前言 JDK,CGLIB,JAVASSIST是常用的动态代理方式. JDK动态代理仅能对具有接口的类进行代理. CGLIB动态代理方式的目标类可以没有接口. Javassist是一个开源的分析.编辑和 ...
- java两种动态代理方式的理解
要理解动态代理,不妨先来看看一个静态代理的例子. 一.静态代理 以一个电商项目的例子来说明问题,比如我定义了一个订单的接口IOrder,其中有一个方法时delivery,代码如下. package c ...
- JDK动态代理和CGLIB字节码增强
一.JDK动态代理 Java 在 java.lang.reflect 包中有自己的代理支持,该类(Proxy.java)用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及 Invocatio ...
- 性能优于JDK代理,CGLib如何实现动态代理
按照代理的创建时期,代理类可以分为两种. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. 动态代理:在程序运行时,运用反射机制动态创建 ...
随机推荐
- TypeScript初识
Typescript 英文官网:https://www.typescriptlang.org/ 中文官网:https://www.tslang.cn/ 介绍 TypeScript 是一种强类型的编程语 ...
- 技术管理进阶——为什么Leader的话有时候你听不懂
原创不易,求分享.求一键三连 Hi,各位亲爱的小伙伴,小钗公号遵循日复盘->周复盘->月复盘->季度复盘->年总结策略,所以某类型文章到后期才会成体系. 今天这篇文章属于「月复 ...
- md5非对称密钥
一.MD5加密概述 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 13 ...
- petite-vue源码剖析-从静态视图开始
代码库结构介绍 examples 各种使用示例 scripts 打包发布脚本 tests 测试用例 src directives v-if等内置指令的实现 app.ts createApp函数 blo ...
- OJ教程--DevC++快捷键
一些常用的快捷键如下: 1.F9编译 2.F10运行 3.F11编译+运行 4.Ctrl + Home键 跳转到当前文本的开头处. 5.Ctrl + End键 跳转到当前文本的末尾处. 6.Ctrl ...
- WPS:编号
独立编号 只想用于表示顺序的编号,不想与标题级别挂钩 样式--编号--选择编号种类后--自定义--按照图片设置 要得到类似这样的编号格式 假设 第一章 系统介绍 为 样式 标题二 1.1 监控管理系统 ...
- LeetCode-031-下一个排列
下一个排列 题目描述:实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须 原地 修 ...
- mysql什么时候会发生file sort
看了网上很多排名很靠前的博客,发现好多都讲错了!我开始按照博客来,没有怀疑,直到自己试了一下才发现是错的. file sort在面试中有时候会问到,这个其实挺能区分是不是真的了解order by的执行 ...
- jmeter + tomcat + ant + svn +jenkins 实现持续集成测试
l 安装jdk时候需要提前检查jdk是否安装成功 l 在dos下输入javac java -version l l 安装jmeter l 校验是否安装成功: l 进入jmeter目录下bin ...
- 解决 MySQL 的 Table is marked as crashed and should be repaired 问题
解决方法: 找到mysql的安装目录的bin/myisamchk工具,在命令行中输入: myisamchk -c -r ../data/mysql/user.MYI 然后myisamchk 工具会帮助 ...