动态代理的实际应用
The following article is from crossoverJie Author crossoverJie
(给ImportNew加星标,提高Java技能)
转自:公众号 crossoverJie 作者:crossoverJie
前言
逐渐偏离主题。。。
示例
@Data
@OriginName("user")
@ToString
public class User extends Model{
@PrimaryId
private Integer id ;
private String name;
private String password ;
@FieldName(value = "city_id")
private Integer cityId ;
private String description ;
}
CREATE TABLE `user`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`description` varchar(100) DEFAULT NULL,
`roleId` int(11) DEFAULT NULL COMMENT '角色ID',
`city_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
)
便可以这样访问数据库。
在初始化 DBHandle 时指定一个回调接口(也就是这里的 UserUpdateListener),便可以在修改数据的时候拿到本次修改的数据实体。
@Slf4j
public class UserUpdateListener implements DataChangeListener{
@Override
public void listener(Object obj) {
log.info("user update data={}", obj.toString());
}
}
实现
DBHandle handle =(DBHandle) new HandleProxy(DBHandle.class).getInstance(new userSaveListener());
下面来看看这个代理类是如何生成的:
主要利用 JDK 自带的 API 实现的,具体参数可以直接参考官方文档:https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html
总之这样便可以创建一个 DBHandler 接口的代理对象,而真正的代理过程是在 InvocationHandler#invoke() 函数中实现的:
这里的实现也是非常简单,在实现完代理对象的业务逻辑后便回调我们传入的事件接口,其中的参数便是当前的数据库 Model 实体对象。
不过需要注意的是,这个事件回调和业务线程是同一个,所以写在这里的逻辑建议都为异步(Hibernate 和 SQLAlchemy 都存在这个情况)。
总结
cglib javassist ASM
RPC 中无感知的远程调用。 Spring 中的 AOP、拦截器等。
看完本文有收获?请转发分享给更多人
关注「ImportNew」,提升Java技能
好文章,我在看❤️