Kafka实战笔记
关于这份笔记,为了不影响大家的阅读体验,我只能在文章中展示部分的章节内容和核心截图
- Kafka入门
- 为什么选择Kafka
- Karka的安装、管理和配置
- Kafka的集群
- 第一个Kafka程序
afka的生产者
- Kafka的消费者
- 深入理解Kafka
- 可靠的数据传递
- Spring和Kalka的整合
- Sprinboot和Kafka的整合
- Kafka实战之削峰填谷
- 数据管道和流式处理(了解即可)
- Kafka实战之削峰填谷
return null;
}
});
println("DriverManager.initialize: jdbc.drivers = " + drivers);
if (drivers == null || drivers.equals(“”)) {
return;
}
String[] driversList = drivers.split(“:”);
println(“number of Drivers:” + driversList.length);
for (String aDriver : driversList) {
try {
println("DriverManager.Initialize: loading " + aDriver);
Class.forName(aDriver, true,
ClassLoader.getSystemClassLoader());
} catch (Exception ex) {
println("DriverManager.Initialize: load failed: " + ex);
}
}
}
在加载DriverManager类的时候会执行loadInitialDrivers方法,方法内通过了两种加载驱动类的方式,分别是:使用系统变量方式和ServiceLoader加载方式;系统变量方式其实就是在变量jdbc.drivers中配置好驱动类,然后使用Class.forName进行加载;下面重点看一下ServiceLoader方式,此处调用了load方法但是并没有真正去加载驱动类,而是返回了一个LazyIterator,后面的代码就是循环变量迭代器:
private static final String PREFIX = “META-INF/services/”;
private class LazyIterator
implements Iterator
{
Class service;
ClassLoader loader;
Enumeration configs = null;
Iterator pending = null;
String nextName = null;
private LazyIterator(Class service, ClassLoader loader) {
this.service = service;
this.loader = loader;
}
private boolean hasNextService() {
if (nextName != null) {
return true;
}
if (configs == null) {
try {
String fullName = PREFIX + service.getName();
if (loader == null)
configs = ClassLoader.getSystemResources(fullName);
else
configs = loader.getResources(fullName);
} catch (IOException x) {
fail(service, “Error locating configuration files”, x);
}
}
while ((pending == null) || !pending.hasNext()) {
if (!configs.hasMoreElements()) {
return false;
}
pending = parse(service, configs.nextElement());
}
nextName = pending.next();
return true;
}
private S nextService() {
if (!hasNextService())
throw new NoSuchElementException();
String cn = nextName;
nextName = null;
Class<?> c = null;
try {
c = Class.forName(cn, false, loader);
} catch (ClassNotFoundException x) {
fail(service,
“Provider " + cn + " not found”);
}
if (!service.isAssignableFrom©) {
fail(service,
“Provider " + cn + " not a subtype”);
}
try {
S p = service.cast(c.newInstance());
providers.put(cn, p);
return p;
} catch (Throwable x) {
fail(service,
“Provider " + cn + " could not be instantiated”,
x);
}
throw new Error(); // This cannot happen
}
…
}
类中指定了一个静态常量PREFIX = “META-INF/services/”,然后和java.sql.Driver拼接组成了fullName,然后通过类加载器去获取所有类路径下java.sql.Driver文件,获取之后存放在configs中,里面的每个元素对应一个文件,每个文件中可能会存在多个驱动类,所以使用pending用来存放每个文件中的驱动信息,获取驱动信息之后在nextService中使用Class.forName加载类信息,并且指定不进行初始化;同时在下面使用newInstance对驱动类进行了实例化操作;每个驱动类中都提供了一个静态注册代码块,比如mysql:
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException(“Can’t register driver!”);
}
}
这里又实例化了一个驱动类,同时注册到DriverManager;接下来就是调用DriverManager的getConnection方法,代码如下:
private static Connection getConnection(
String url, java.util.Properties info, Class<?> caller) throws SQLException {
/*
-
When callerCl is null, we should check the application’s
-
(which is invoking this class indirectly)
-
classloader, so that the JDBC driver class outside rt.jar
-
can be loaded from here.
*/
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
synchronized(DriverManager.class) {
// synchronize loading of the correct classloader.
if (callerCL == null) {
callerCL = Thread.currentThread().getContextClassLoader();
}
}
if(url == null) {
throw new SQLException(“The url cannot be null”, “08001”);
}
println(“DriverManager.getConnection(”" + url + “”)");
// Walk through the loaded registeredDrivers attempting to make a connection.
// Remember the first exception that gets raised so we can reraise it.
SQLException reason = null;
for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
if(isDriverAllowed(aDriver.driver, callerCL)) {
try {
println(" trying " + aDriver.driver.getClass().getName());
Connection con = aDriver.driver.connect(url, info);
if (con != null) {
// Success!
println("getConnection returning " + aDriver.driver.getClass().getName());
return (con);
}
} catch (SQLException ex) {
if (reason == null) {
reason = ex;
}
}
} else {
println(" skipping: " + aDriver.getClass().getName());
}
}
// if we got here nobody could connect.
if (reason != null) {
println("getConnection failed: " + reason);
throw reason;
}
println("getConnection: no suitable driver found for "+ url);
throw new SQLException("No suitable driver found for "+ url, “08001”);
}
此方法主要是遍历之前注册的DriverInfo,拿着url信息去每个驱动类中建立连接,当然每个驱动类中都会进行url匹配校验,成功之后返回Connection,如果中途有失败的连接并不影响尝试新的驱动连接,遍历完之后还是无法获取连接,则抛出异常;
4.扩展
如果想扩展新的驱动类也很简单,只需要在类路径下创建META-INF/services/文件夹,同时在里面创建java.sql.Driver文件,在文件中写入具体的驱动类名称,当然此类需要继承java.sql.Driver接口类;例如实例中提供的TestDriver。
序列化实战
1.准备接口类
public interface Serialization {
/**
-
序列化
-
@param obj
-
@return
*/
public byte[] serialize(Object obj) throws Exception;
/**
-
反序列化
-
@param param
-
@param clazz
-
@return
-
@throws Exception
*/
public T deserialize(byte[] param, Class clazz) throws Exception;
/**
-
序列化名称
-
@return
*/
public String getName();
Java高频面试专题合集解析:
当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!
更多Java架构进阶资料展示
4)]
当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!
[外链图片转存中…(img-kr8SxjPw-1714853150105)]
更多Java架构进阶资料展示
[外链图片转存中…(img-EdaooC4t-1714853150105)]
[外链图片转存中…(img-B745rn6E-1714853150105)]
[外链图片转存中…(img-vsm3AWNM-1714853150106)]