开发者学堂课程【高校精品课-上海交通大学-企业级应用体系架构:Distributed Object 2】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/75/detail/15822
Distributed Object 2(一)
内容介绍:
一、Establishing Connection
二、Java Naming and Directory Interface
三、Get InitialContext
四、DataSource in Tomcat
五、The RMI Programming Model
六、Transferring Nonremote Objects
一、Establishing Connection
数据库在创建连接的时候有两种方式,一种是通过 DriverManager 方式,另外一种是通过 DataSource 的方式。
DriverManager
- registerDriver and getConnection
package sample;
import java.sql.Connection;
import java.sq1.DriverManager;
import java.sq1.SQLException;
public class AccessDB {
public static void main(String[] args) throws
ClassNotFoundException, SQLException
{
Class.forName( "com.mysql.jdbc.Driver");
String url = "jdbc:mysq1://localhost:3306";
String user = "root" ;
String passwd = "12345678" ;
Connection con = DriverManager . getConnection(url, user, passwd);
System.out.println(con.getTransactionIsolation());
}
通过 DriverManager 的方式,要求直接在代码里写死,加载一个驱动类,然后说清楚它的 url、用户名密码,然后通过 DriverManager 就 get connection 传递这三个产品就可以。在 DriverManager 里面,它实际上加载了很多驱动类,于是它就拿着 url 一个一个去问你认识不认识,比如先加载的是 Oracle 的驱动类,然后是 MySQL 的,然后还有 DB2的,Oracle 说我不认识这种 url,所以我不处理,再接着往下问,MySQL 说我认识,它就用 MySQL 的驱动类去获取的连接。这种方式的不好就是在代码里跟具体访问的数据源绑定了它必须在什么位置上,在哪个端口上,是哪一种数据库,但我们希望是跟它们要解耦,所以引入了像 DataSource 这种方式。DataSource 就要用到 JNDI 树,JNDI 树提供一个树,什么叫命名和目录树,因为它是一种目录结构,是这样的目录结构,它里面每一个地方绑的都是限制对,所以在这里可以看到在 JNDI 树上就可以把这些参数给它绑定,具体做法是什么呢?
package sample;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
public class Server {
public static void main(String[] args) throws ClassNotFoundException,
SQLException, NamingException
{
MysqlDataSource ds = new MysqlDataSource();
ds.setServerName( "localhost");
ds.setPortNumber(3306) ;
ds.setUser("root");
ds.setPassword("12345678");
Context namingContext = new InitialContext();
}
namingContext.bind(" rmi://localhost:1099/datasource", ds);
}
}
当时还给了一个代码,比如在绑定 JNDI 树,这个是服务器端的代码,新创建一个 DataSource,然后设置好它的位置、端口、用户名、密码,然后创建一个InitialContext,创建好之后,把 DataSource 绑到这棵树里去。所谓的这个树不止一个是什么意思呢?
二、Java Naming and Directory Interface
JNDI 只是一种接口,它的实现有 LDAP,就是轻量级目录访问协议或者域名服务器,有 RMI,还有更古老的 CORBA,大家现在可能不用了。所谓 SPI 说的是service 的编程接口,也就是说,如果实现了一种 JNDI 的服务,那么就必须要实现这些接口,Java 才认你是一个标准的 JNDI 服务。这些东西都实现,可以设想在一台服务器上挂一个 LDAP 的实现,挂一个 RMI 的实现,这些东西同时运行在一台机器上,这是不矛盾的,所以不但要指定这台机器在哪里,整个 JNDI服务它在哪个端口上,还得去指定是哪一棵树。怎么指定是哪一棵树呢?就是访问任何一棵树的时候都要用到 InitialContext,缩写就是 IC。IC 的工厂类不同,就指的要访问的类不同,如果用 LDAP 的工厂类创建一个 IC,那它就只能给你发 LDAP 的目录数的根对象,如果用的是 RMI 的工厂类,它就会给你发一个 RMI 的 InitialContext,你就访问到这棵树上。
package sample;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
public class Client {
public static void main(String[] args) throws
NamingException,RemoteException,SQLException
{
Context namingContext = new InitialContext();
String url = "rmi://localhost:1099/datasource" ;
MysqlDataSource ds = (MysqlDataSource) namingContext.lookup(ur1);
Connection con = ds.getConnection(" root", "12345678");
System.out.println(con.getTransactionIsolation());
}
}
所以必须要指定这两个属性,指定这两个属性之后,看客户端代码,服务器这端把创建的 ds 的数据源绑到了 RMI 的注册表里面,就是本地的一个注册表,在1099这个端口,绑上去以后叫 datasource,也就是说,在本地可能会有一个 LDAP 的树,还有一个 RMI 的这样一棵树,把它绑到 RMI 这棵树底下,因为前面不带前缀,所以它有一个名字叫 datasource,它真正对应的存的就是它的 key,它的 value 是 ds 的这个地址。
服务器端绑好之后就上客户端这边,首先要创建 InitialContext,Initial 就是初始的,Context 就是上下文,相当于要到达这棵树的根,到达了以后要找在rmi://localhost:1099/datasource 这个位置上 datasource 名字的中心,找回之后,因为这边绑的时候就是箭直对,会返这个引用,但是在整个 JNDI 树上绑的各种各样对象都有可能,所以找回来之后要强制转换它的类型,于是就得到了这个远程对象。