最后如何让自己一步步成为技术专家
说句实话,如果一个打工人不想提升自己,那便没有工作的意义,毕竟大家也没有到养老的年龄。
当你的技术在一步步贴近阿里p7水平的时候,毫无疑问你的薪资肯定会涨,同时你能学到更多更深的技术,交结到更厉害的大牛。
推荐一份Java架构之路必备的学习笔记,内容相当全面!!!
成年人的世界没有容易二字,前段时间刷抖音看到一个程序员连着加班两星期到半夜2点的视频。在这个行业若想要拿高薪除了提高硬实力别无他法。
你知道吗?现在有的应届生实习薪资都已经赶超开发5年的程序员了,实习薪资26K,30K,你没有紧迫感吗?做了这么多年还不如一个应届生,真的非常尴尬!
进了这个行业就不要把没时间学习当借口,这个行业就是要不断学习,不然就只能被裁员。所以,抓紧时间投资自己,多学点技术,眼前困难,往后轻松!
【关注】+【转发】+【点赞】支持我!创作不易!
// 如果之前初始化的时候报错了,那么错误会被记录下来并缓存在此处,直接抛出
// 此处的设计应该是减少锁消耗
if (createAdaptiveInstanceError != null) {
throw new IllegalStateException("Failed to create adaptive instance: " + createAdaptiveInstanceError.toString(),
createAdaptiveInstanceError);
}
synchronized (cachedAdaptiveInstance) {
// 双锁验证
instance = cachedAdaptiveInstance.get();
if (instance == null) {
try {
// 创建实例并存储在 Holder 对象里
instance = createAdaptiveExtension();
cachedAdaptiveInstance.set(instance);
} catch (Throwable t) {
// 如果报错了就会把错误存储起来
createAdaptiveInstanceError = t;
throw new IllegalStateException("Failed to create adaptive instance: " + t.toString(), t);
}
}
}
}
// 返回对象实例
return (T) instance;
}
2 createAdaptiveExtension
创建实例对象:
// org.apache.dubbo.common.extension.ExtensionLoader
private T createAdaptiveExtension() {
try {
// getAdaptiveExtensionClass().newInstance() 方法会使用 Class 对象的 newInstance() 方法创建一个对象
// injectExtension(…) 则会对创建出来的对象进行依赖注入
return injectExtension((T)getAdaptiveExtensionClass().newInstance());
} catch (Exception e) {
throw new IllegalStateException("Can’t create adaptive extension " + type + ", cause: " + e.getMessage(), e);
}
}
3 injectExtension
// org.apache.dubbo.common.extension.ExtensionLoader
private T injectExtension(T instance) {
// objectFactory 是用来依赖注入的 ExtensionFactory
// 如果 objectFactory 为空,就直接返回
// 需要注意的是,只有非 ExtensionFactory 的 loader 才有 objectFactory
if (objectFactory == null) {
return instance;
}
try {
// 轮训实例对象中所有的方法
for (Method method : instance.getClass().getMethods()) {
// 如果方法不是 set 方法就跳过
// 此处可以理解为,dubbo 的 spi 依赖注入需要 set 方法支持
if (!isSetter(method)) {
continue;
}
// 如果方法被标注了 DisableInject 注解就跳过
if (method.getAnnotation(DisableInject.class) != null) {
continue;
}
// 如果方法的参数是原始类型就跳过
// 依赖注入需要使用包装类型
Class<?> pt = method.getParameterTypes()[0];
if (ReflectUtils.isPrimitives(pt)) {
continue;
}
try {
// 反射注入
String property = getSetterProperty(method);
Object object = objectFactory.getExtension(pt, property);
if (object != null) {
method.invoke(instance, object);
}
} catch (Exception e) {
logger.error("Failed to inject via method " + method.getName()
- " of interface " + type.getName() + ": " + e.getMessage(), e);
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return instance;
}
##三 ExtensionFactory
ExtensionFactory 是用来依赖注入的工厂:
@SPI
public interface ExtensionFactory {
T getExtension(Class type, String name);
}
该接口在 Dubbo 中有三个默认实现类:
org.apache.dubbo.config.spring.extension.SpringExtensionFactory
org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory
org.apache.dubbo.common.extension.factory.SpiExtensionFactory
在开发中 SpringExtensionFactory 应该会用的更广泛一些,本示例中此处暂时不展开。
1 AdaptiveExtensionFactory
AdaptiveExtensionFactory 是默认工厂:
import org.apache.dubbo.common.extension.Adaptive;
import org.apache.dubbo.common.extension.ExtensionFactory;
import org.apache.dubbo.common.extension.ExtensionLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {
private final List factories;
// 构造器
public AdaptiveExtensionFactory() {
ExtensionLoader loader
= ExtensionLoader
.getExtensionLoader(ExtensionFactory.class);
// AdaptiveExtensionFactory 会将 SpiExtensionFactory 和 SpringExtensionFactory 放置在 factories 列表里
List list = new ArrayList();
for (String name : loader.getSupportedExtensions()) {
list.add(loader.getExtension(name));
}
factories = Collections.unmodifiableList(list);
}
// 使用 AdaptiveExtensionFactory 去获取实体类的时候,
// 会调用 spi 或者 spring 的 ext 工厂去尝试获取实体类
@Override
public T getExtension(Class type, String name) {
for (ExtensionFactory factory : factories) {
T extension = factory.getExtension(type, name);
if (extension != null) {
return extension;
}
}
return null;
}
}
2 SpiExtensionFactory
import org.apache.dubbo.common.extension.ExtensionFactory;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.SPI;
public class SpiExtensionFactory implements ExtensionFactory {
@Override
public T getExtension(Class type, String name) {
// spi 工厂用于解析 spi 注解
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
// 如果传入的 type 是一个被 spi 注释的接口,那么会初始化一个它的 class loader
ExtensionLoader loader
= ExtensionLoader.getExtensionLoader(type);
// 初始化对象
if (!loader.getSupportedExtensions().isEmpty()) {
return loader.getAdaptiveExtension();
}
}
return null;
}
}
##四 getExtension
回到 demo :
SpiDemoService one = loader.getExtension(“one”);
1 getExtension
// org.apache.dubbo.common.extension.ExtensionLoader
public T getExtension(String name) {
// 非空验证,忽略
if (StringUtils.isEmpty(name)) {
throw new IllegalArgumentException(“Extension name == null”);
}
// 默认机制,会去找名称为 dubbo 的实例
// 一般用不到
if (“true”.equals(name)) {
return getDefaultExtension();
}
// 如果之前不存在这个名称对应的 Holder 对象,此处会创建一个空白的 Holder
// 调用 get() 方法会获得空对象
final Holder holder = getOrCreateHolder(name);
Object instance = holder.get();
if (instance == null) {
synchronized (holder) {
instance = holder.get();
if (instance == null) {
// 创建对象实例,并装进 holder 中
instance = createExtension(name);
holder.set(instance);
}
}
}
// 返回实例
return (T) instance;
}
2 createExtension
// org.apache.dubbo.common.extension.ExtensionLoader
private T createExtension(String name) {
// 如果 class 不存在就报错
Class<?> clazz = getExtensionClasses().get(name);
if (clazz == null) {
throw findException(name);
}
try {
// 尝试获取 class 对应的实例,如果不存在就创建
T instance = (T) EXTENSION_INSTANCES.get(clazz);
if (instance == null) {
EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
instance = (T) EXTENSION_INSTANCES.get(clazz);
}
// 进行依赖注入
injectExtension(instance);
Set<Class<?>> wrapperClasses = cachedWrapperClasses;
if (CollectionUtils.isNotEmpty(wrapperClasses)) {
for (Class<?> wrapperClass : wrapperClasses) {
instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
}
}
initExtension(instance);
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
type + ") couldn’t be instantiated: " + t.getMessage(), t);
}
}
最近我根据上述的技术体系图搜集了几十套腾讯、头条、阿里、美团等公司21年的面试题,把技术点整理成了视频(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分
able t) {
throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
type + ") couldn’t be instantiated: " + t.getMessage(), t);
}
}
[外链图片转存中…(img-F8w1RtT1-1715258418392)]
最近我根据上述的技术体系图搜集了几十套腾讯、头条、阿里、美团等公司21年的面试题,把技术点整理成了视频(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分
[外链图片转存中…(img-vDVCGKto-1715258418393)]