Ctrip Apollo源码阅读
1、切点的选择
// 切点的定义
@Pointcut("execution(public * org.spring.liong.Repository+.*(..))")
public void anyRepository(){
}
// 切点的使用
@Aroud("anyRepository")
public Object invoke(ProceedingJointPoint point) {
}
aspectJ技术不常用,但是非常好用。告诉spring创建一个切面对象,它就可以工作了。
假设我们引入了相应的包,会不会给我们自己的对象,生产相应的注解呢?这个就要看切点的选择了,所以限定包,可以防止滥用。
切点定义的几种样式:AspectJ——切入点语法(1)之捕获方法上的连接点)
2、注解的使用
注解是jdk自带的功能,能通过反射获取其注解。
package com.yk.annotation;
import java.lang.annotation.*;
@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
@Inherited
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation {
String value() default "hello";
String message() default "aaa";
}
aspectJ也能通过注解,建立切点。同时我们也可以扫描全包
3、Spring BeanUtils的使用
BeanUtil主要用于对象属性的复制,但是,它会把目标对象的null值也copy过来,这可能是我们不想要的。这时需要将null属性剔除。
//忽略null值
public static String[] getNullpropertyName(Object source) {
//使用BeanWrapper封装传入的类
BeanWrapper beanWrapper = new BeanWrapperImpl(source);
//获取bean类所有的属性定义
PropertyDescriptor[] pds = beanWrapper.getPropertyDescriptor();
Set<String> emptyNames = new HashSet<>();
for(PropertyDescriptor pd : pds) {
//获取属性值
Object beanValue = beanWrapper.getPropertyValue(pd.getName());
if(beanValue == null)
empryNames.add(pd.getName());
}
String [] results = new String[emptyNames.size()];
return emptyNames.toArray(results);
}
BeanWrapper在get/set属性时,非常好用
4、Class.forName的使用
public DataSource datasource() throws Exception{
Class clazz = Class.forName("com.ctrip.datasource.configure.DalDataSourceFactory");
Object obj = class.newInstance();
// 反射获取方法
Method method = clazz.getMethod("createDataSource",String.class,String.class);
DataSource ds = (DataSource)method.invoke(obj,this.settings.getTitanDbname(),this.settings.getTitanUrl());
return ds;
}
此处为什么使用forName加载,而不是ClassLoader,原因是Class.forName()在加载com.mysql.jdbc.Driver时,会执行静态代码块,向DriverManager注册自己
在Java的反射中,Class.forName和ClassLoader的区别
关于Class.forName是否破坏了双亲委派模型,这个还得商量。关键点估计是Driver类的加载时机,如果我们先使用Class.forName加载了,那在DriverMangeer就不用加载了。否则就会加载,并且使用ThreadContextClassLoader,就产生了破坏。
5、Environment变量读取
使用了Spirng提供的接口,其核心代码是
MapProperteSource的类的使用
RefreshablePropertySource source = new RefresPropertySource();
this.environment.getPropertySources().addLast(souce);
主要是ConfigureableEnvironment的使用
6、java语言的spi机制
什么是spi呢?好像我们也很少用到
SPI ( Service Provider Interface),是一种服务发现机制。
SPI 的本质是将接口的实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载对应接口的实现类。这样就可以在运行时,获取接口的实现类。
与 JDK SPI 类似, 相对于 Java 的 SPI 的优势在于:
Spring SPI 指定配置文件为 classpath 下的 META-INF/spring.factories,所有的拓展点配置放到一个文件中。
配置文件内容为 key-value 类型,key 为接口的全限定名, value 为 实现类的全限定名,可以为多个
所以说,有了这个技术,在springboot中,使用redis,就像使用jdbc一样丝滑
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?