开发者学堂课程【高校精品课-上海交通大学-企业级应用体系架构: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
三、Get InitialContext
一旦得到它,就跟访问本地对象一样,跟 rmi 一样,要获取连接,InitialContext 里需要参数,一种方法是直接创建一个 Hash 表或者 Hashmap,
Hashtable env = new Hashtable();
env.put( Context.INITIAL_ CONTEXT_ FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put (Context.PROVIDER_ URL, "t3://localhost:7001");
InitialContext ctx = new InitialContext(env);
把参数的值放进去,这里放了两个参数,一个是它的 url,一个是 ContextFactory,把它放进去之后,用它做参数创建 InitialContext。
还有一种,就是写一个 jndi.properties 文件,里面写的是这两个属性,
java.naming.factory.initial=
org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
就是 initial context factory 是谁?另外就是它的 url 是谁?RMI 里面所谓的用注册表来实现,以及这里 source 对它的绑定是一回事,它的原理一模一样,唯一要注意的是,这个文件不一定要放到 client 或者是 server 的同一个目录里,实际上只要求放到 classpath 里就可以,在类路径里面有一个问题,就是看你的类路径是怎么写的。在编写程序的时候还会碰上这样一个问题,在 A 这个应用里面用的是 jnp 的 initial context factory,在应用 B 里面,它用的可能是别的,比如 jboss,在其他应用里面可能用的也不一样,也就是说它们各自配的 jndi.properties 文件是不一样的。所以一个比较好的方法是把 jndi.properties 文件,是哪个应用的就放到哪个应用的目录里,这样它们之间不会有冲突,不会引用错了。然后在 classpath 里面第一个路径一定是点,就是当前路径,这样 A 在运行的时候,当你没有参数的时候, Java 自己就会去找这个 jndi.properties 条件。当在 A 应用里面,用无参数的构造器创建 initial context 的时候,首先,它会在第一个类路径里找,找它自己配的 jndi.properties。B 同样是这样,如果当前路径不是第一个路径,把它配成比如 home 路径,那会造成了什么问题呢?在 home 路径里面,如果某一天真的在上面放了个 jndi.properties 条件,也就意味着所有的应用在跑的时候,它们如果没有用参数去创建 initial context,这样就到内路径里面跑,内路径里面有顺序,一跑它就发现后面也有,所以无论怎么去编写自己的 jndi 文件,就会发现它都在用这一个,所以内路径里面第一个一定要是当前路径,这样就区分开了。
Jndi 服务、rmi 注册表就是一个很大的 keyvalue 存储,k 就是一个名字,v就是对象的引用,就知道它的工作原理,就是要拿这个名字来找对象引用,按道理来说,对象的引用实际上就是个地址,就是一串字符串。比如拿一个对象直接 client 它,它出来就是一串 ID,这个ID 没什么问题,但这些东西不好记,它不如名字形象好记,所以大家提供这样一个服务,按名字去找,找完之后把对应的值,就对账的应用返回给你,这就是 rmi,或者名字服务它要做的事情,这就是 rmi 的注册表,所以 rmi 的注册表是 gndi 的一种,可以用 rmi 定别的,刚才讲 rmi 的注册表就是这个作用。
四、DataSource in Tomcat
当时给大家讲一个开发程序的时候,要写一个 context.xml。
auth= "Container"
type="javax.sq1.DataSource"
maxActive="100"
maxIdle="30"
maxWait= "10000"
username=" root"
password="12345678"
driverClassName= "com.mysql.jdbc.Driver"
ur1="jdbc:mysq1://localhost:3306/sample_ one"/>
在里面写的名字就是绑到了在 tomcat 跑起来之后,它就有一个 JNDI 服务,就是绑在 JNDI 树上的这个服务,这个数据源它到底叫什么?也就是说,在本地 MySQL 数据库有一个叫做 sample_one 的数据库,它绑到这棵树上的时候,它就叫了这么个名字,所以在代码里始终出现的是这个名字 jdbc/sample,找这个名字找不到的时候,它就要到这棵树上找,就是在当前这个页面里,它找不到这个变量的时候,它就要到 jndi 树里找,它一找就找到了你通过这个文件绑定上的信息,这个对象就是这个数据库,所以实际上前面这一个文件,它处理的就是这个数据库,用这种方式的一个好处是什么呢?代码写完之后,要访问数据源,这代码写的不错,有很多人都想复用,A 应用复用,B、C 这两个应用都要复用,但在A 应用里面,它背后的数据库可能叫 one,是一个 MySQL 的数据库,B 应用里面,那个数据库叫 two,它可能是个 DB2的数据库,C 应用里面,这个数据库叫 three,它是一个比如 Oracle 的数据库,如果这个页面写的非常好,别人想去复用,但是在它们环境里数据库都不一样,那怎么办呢?这个代码显然是不能改的,因为代码可能写得很多,让别人去改代码太麻烦了,怎么办呢?就会在写代码说明,我会访问一个数据库,但这个数据库你们自己去绑,到你们的应用环境里面,A、B、C 三个应用拿去以后,自己去跟环境里的数据库绑定,我只说我要访问这样的数据源,所以 A、B、C 在拿到这个页面之后,它配自己的context.xml 的时候,在这里就可以去配,代码里出现的这个数据源,实际上,在当前环境里,它可能使用了这个 driver,也可能使用别的 driver,它的位置在哪里,名字怎么变化等等,可以按照自己的意愿去配,但是不管怎么配,这个页面都可以正常执行,因为通过这种名字绑定,实际上是改变了 key 和 value绑定的关系,key 在不同的应用里和不同的 value的绑定,实现了 text.jsp,它跟实际的运营环境的绑定,所以页面独立于具体的运营环境,A、B、C 的运营环境不管,想用就配一个就叫 jdbc/sample 的数据源。具体数据源在哪里,自己去配,所以前端的可复用的程序和具体的运行环境的绑定,当时写的 context.xml 为什么能访问到?就是用的这套东西。