首页 > 其他分享 >Lottery lec10-cnblog

Lottery lec10-cnblog

时间:2024-01-14 17:48:02浏览次数:34  
标签:Lottery final lec10 对象 class cnblog 注解 方法 public

Lottery lec10

lec10 主要实现的是一个路由中间件,用来选择对应的分库和分表。

下面主要介绍在阅读代码中遇到的基础知识点和业务相关内容。

@ConditionalOnMissingBean注解

它是修饰bean的一个注解,主要实现的是,当你的bean被注册之后,如果而注册相同类型的bean,就不会成功,它会保证你的bean只有一个,即你的实例只有一个,当你注册多个相同的bean时,会出现异常,以此来告诉开发人员。

@ConditionalOnMissingBean真正意义在于它的扩展性,即当你封装一个组件时,你的组件有个默认的实现类,这时为默认的实现类bean上,添加@ConditionalOnMissingBean;而在外部,开发人员根据业务定义自己的bean,这时它就有意义了,当在外部出现多个相同类型bean时,spring会为我们选择不带@ConditionalOnMissingBean注解的实现;也就是说@ConditionalOnMissingBean是当没有个性化bean时,提供一个默认的bean,这才是它的意义!

Aspect注解
@Aspect:作用是把当前类标识为一个切面供容器读取

@Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。
@Around:环绕增强,相当于MethodInterceptor
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterThrowing:异常抛出增强,相当于ThrowsAdvice
@After: final增强,不管是抛出异常或者正常退出都会执行

由此引入一个新的知识点:

自定义注解实现AOP方式:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface DBRouter {

    String key() default "";
}

// 实现自定义注解
// Target表明注解作用于类型和方法上
// Retention表明在运行时起作用
// Documented方便文档生成工具来生成文档

Aop部分

@Aspect
public class DBRouterJoinPoint {
    
    @Pointcut("@annotation(cn.bugstack.middleware.db.router.annotation.DBRouter)")
    public void aopPoint() {
    }
    // 增强方法的Aop实现
    @Around("aopPoint() && @annotation(dbRouter)")
    public Object doRouter(ProceedingJoinPoint jp, DBRouter dbRouter) throws Throwable {
        
    }
}

JointPoint使用

上面代码中的ProceedingJoinPoint继承自JointPoint。这个JointPoint的意思就是切入点,那我们需要获取到切入点的什么信息呢?

  1. 切入点的方法名字及其参数
  2. 切入点方法标注的注解对象(通过该对象可以获取注解信息)
  3. 切入点目标对象(可以通过反射获取对象的类名,属性和方法名)
    注:有一点非常重要,Spring的AOP只能支持到方法级别的切入。换句话说,切入点只能是某个方法。
// 获取切入点所在的目标对象
Object obj = jointpoint.getTarget();
Class class1 = obj.getClass()
    
// 获取切入点方法的名字
String methodName = joinPoint.getSignature().getName()
// 获取切入点方法的参数
Object[] args = joinPoint.getArgs();

// 获取方法上的注解对象

 Signature signature = joinPoint.getSignature();
 MethodSignature methodSignature = (MethodSignature) signature;
 Method method = methodSignature.getMethod();

 if (method != null)
 {
      xxxxx annoObj= method.getAnnotation(xxxxxx.class);
 }
 return null;


instanceof关键字
instanceof是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false
ps:
	null用instanceof跟任何类型比较时都是false
	左边的对象实例不能是基础数据类型

在继续项目过程中,使用了反射的技术从对象中获取某一种属性的值

下面再去细致学习一下反射的知识

反射

反射的概念:是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意属性和方法;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。

获取字节码文件对象的三种方式

// 1. class.forName(全类名)
Class class1 = Class.forName("com.itheima.reflectdemo.Student");

// 2. 通过class属性
Class class2 = Student.class;

//因为class文件在硬盘中是唯一的,所以,当这个文件加载到内存之后产生的对象也是唯一的
System.out.println(class1 == class2);  // true

// 3. 通过对象方式获取
Student stu = new Student();
Class class3 = stu.getClass();
System.out.println(clazz1 == clazz2);//true
System.out.println(clazz2 == clazz3);//true

解释一下字节码文件和字节码文件对象这两个概念:

字节码文件是java程序编译后生成的.class文件,字节码文件对象是class文件加载到内存后,虚拟机自动创建出来的对象。这个对象里面至少包含了:构造方法,成员变量,成员方法。

反射就是获取字节码文件对象,这个对象在内存中是唯一存在的。

简单来说,就是可以通过class字节码对象,来创建对象、获取对象的私有属性值等操作,拥有了class字节码对象,就可以对类和对象任意进行操作

java移位运算符

<< : 左移运算符,num << 1,相当于num乘以2

>> : 右移运算符,num >> 1,相当于num除以2

>>> : 无符号右移,忽略符号位,空位都以0补齐

Mybatis拦截器

学习一个技术,首先应该去理解,其是用来解决什么问题?能够用来做什么?

在当前场景中,通过路由,可以得到dbIdx和tbIdx这两个分库分表的索引,那么如何将索引插入sql语句当中呢?

mybatis拦截器可以做的工作就是:SQL修改、分页操作、数据过滤、SQL执行时间性能监控

mybatis的核心部件有什么呢?

Configuration:初始化基础配置,比如Mybatis别名
SqlSessionFactory:SqlSession工厂
SqlSession:作为Mybatis工作的主要顶层API,表示和数据库交互的会话,完成必要的数据库增删改查功能
Executor:MyBatis的内部执行器,它负责调用StatementHandler操作数据库,并把结果集通过ResultSetHandler进行自动映射,另外,它还处理二级缓存的操作。
StatementHandler:MyBatis直接在数据库执行SQL脚本的对象。另外它也实现了MyBatis的一级缓存
ParameterHandler:负责将用户传递的参数转换成JDBC Statement所需要的参数。是MyBatis实现SQL入参设置的对象。
ResultSetHandler:负责将JDBC返回的ResultSet结果集对象转换成List类型的集合。是MyBatis把ResultSet集合映射成POJO的接口对象。
TypeHandler:负责Java数据类型和JDBC数据类型之间的映射和转换。
MappedStatement:MappedStatement维护了一条<select|update|delete|insert>节点的封装。
SqlSource :负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回。
BoundSql:表示动态生成的SQL语句以及相应的参数信息。

mybatis执行过程

image-20240113125628764

下面介绍mybatis拦截器:

先看一下下面的代码

@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class DynamicMybatisPlugin implements Interceptor {
}

在代码中,困惑我的地方就在于Intercepts注解和Signature注解

@Intercepts:标志该类是一个拦截器;
@Signature:标志拦截器需要拦截哪一个接口的哪一个方法
    type:四种类型接口(Executor 拦截执行器方法、StatementHandler 拦截SQL语法构建处理、 ParmeterHandler 拦截参数处理、ResultSetHandler 拦截结果集处理)的某一个接口;
	method:对应接口中的某一个方法名;
	args:对应接口中某一个方法的参数(因为重载);

接口Interceptor有三个接口方法:

public class DynamicMybatisPlugin implements Interceptor {
	// 进行拦截时要执行的方法
    // Invocation有三个字段
    // private final Object target;
    // private final Method method;
    // private final Object[] args;
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        return null;
    }
	// 插件用于封装目标对象的,通过该方法我们可以返回目标对象本身,也可以返回一个它的代理,可		以决定是否要进行拦截进而决定要返回一个什么样的目标对象,官方提供了示例:return 				Plugin.wrap(target, this);,可以在这个方法中提前进行拦截对象类型判断,提高性能:
    @Override
    public Object plugin(Object target) {
        return null;
    }
	// 设置一些拦截器需要用到的变量参数
    @Override
    public void setProperties(Properties properties) {

    }
}

在项目中,代码中拦截了StatementHandler对象,这个接口方法如下:

image-20240113131404794

prepare: 用于创建一个具体的 Statement 对象的实现类或者是 Statement 对象

parametersize: 用于初始化 Statement 对象以及对sql的占位符进行赋值

update: 用于通知 Statement 对象将 insert、update、delete 操作推送到数据库

query: 用于通知 Statement 对象将 select 操作推送数据库并返回对应的查询结果

由于分库分表操作需要将数据库id和表id,填入sql语句中,在更改sql语句过程中,使用了正则表达式(又是知识盲区​,​之前​虽然​知道​正则表达式​的​作用​,​但​没有​实际​使用过

标签:Lottery,final,lec10,对象,class,cnblog,注解,方法,public
From: https://www.cnblogs.com/xyfhsy/p/17963941

相关文章

  • obsidian-sync-cnblog
    tags:obsidian插件开发TypeScriptauthor:zhangleidata:2023-12-19开始项目简介由于Markdown语法的便捷性,我们从繁重的排版布局工作中解脱出来,越来越多的人开始接受这种写作方式,该插件可以将你的md笔记,方便的同步到博客园中,即使你是使用的本地图片,也无须担......
  • Lottery学习记录
    进度环境、配置、规范搭建(DDD+RPC)架构跑通广播模式RPC过程调用抽奖活动策略库表设计抽奖策略领域模块开发遇到的问题(第三节)跑通RPC调用例子时失败,经过仔细比对+研究issue发现是dubbo的服务端注解service是spring的,改为dubbo的service注解就可以了用一台新电......
  • 博客园cnblogs的代码折叠
    实现折叠的代码如下:<details><summary>查看代码</summary><pre><code>这里写需要被折叠的代码</code></pre></details>效果如下:查看代码这里写需要被折叠的代码参考链接:https://www.cnblogs.c......
  • scrapy解析数据,配置文件,整站爬取cnblogs,持久化
    1scrapy解析数据......
  • cnblogs 侧边栏
    <scripttype="text/javascript">window.cnblogsConfig={info:{name:'Martian148',//用户名||不配置默认取博客园名称startDate:'2018-10-13',//入园时间,年-月-日。入园时间查看方法:鼠标停留园龄时间上,会显示入园时间......
  • JVM系列-第7章-对象的实例化内存布局与访问定位-cnblog
    title:JVM系列-第7章-对象的实例化内存布局与访问定位tags:-JVM-虚拟机categories:-JVM-1.内存与垃圾回收篇keywords:JVM,虚拟机。description:JVM系列-第7章-对象的实例化内存布局与访问定位。cover:'https://gitee.com/youthlql/randombg/raw/master/lo......
  • JVM系列-第9章-StringTable(字符串常量池)-cnblog
    title:JVM系列-第9章-StringTable(字符串常量池)tags:-JVM-虚拟机categories:-JVM-1.内存与垃圾回收篇keywords:JVM,虚拟机。description:JVM系列-第9章-StringTable(字符串常量池)。cover:'https://gitee.com/youthlql/randombg/raw/master/logo/jvm.png......
  • JVM系列-第8章-执行引擎-cnblog
    title:JVM系列-第8章-执行引擎tags:-JVM-虚拟机categories:-JVM-1.内存与垃圾回收篇keywords:JVM,虚拟机。description:JVM系列-第8章-执行引擎。cover:'https://gitee.com/youthlql/randombg/raw/master/logo/jvm.png'abbrlink:408712f4date:2020-11......
  • JVM系列-第10章-垃圾回收概述和相关算法-cnblog
    title:JVM系列-第10章-垃圾回收概述和相关算法tags:-JVM-虚拟机categories:-JVM-1.内存与垃圾回收篇keywords:JVM,虚拟机。description:JVM系列-第10章-垃圾回收概述和相关算法。cover:'https://gitee.com/youthlql/randombg/raw/master/logo/jvm.png'ab......
  • JVM系列-第12章-垃圾回收器-cnblog
    title:JVM系列-第12章-垃圾回收器tags:-JVM-虚拟机categories:-JVM-1.内存与垃圾回收篇keywords:JVM,虚拟机。description:JVM系列-第12章-垃圾回收器。cover:'https://gitee.com/youthlql/randombg/raw/master/logo/jvm.png'abbrlink:7706d61ddate:2......