JNDI
JNDI全称:Java Naming and Directory Interface,Java命名和目录接口。
- JNDI:是一个有关应用序设计的 API 为开发人员提供了查找和访问各种命名和目录服务的通用、 统一的接口;
- 作用:通过名称将资源与服务进行关联。
JNDI的作用与优点
-
在应用与Java对象或资源之间建立松耦合的逻辑关联,简化应用对于资源的配置及维护工作;
-
可以在更大范围、不同应用之间共享资源;
JNDI 简单地理解为是一种将对象和名字绑定的技术,即指定一个资源名称,将该称与某一资源或服务相关联,当需要访问其他组件和资源时,就需要使用 JNDI 服务进行定位. 应程序可以通过名字获取对应的对象或服务;
用法
-
在 Tomcat 中发布一条信息供所有的 Web 应用程序使用;
分析:Tomcat 根目录\conf\context.xml 文件为全局的上下文配置文件,所有的 Web 应用有效。所将要发布的信息配置在此文件中,再通过 JNDI 来查找信息;
1. 在 Tomcat 中发布一条信息,修改context . xml 文件,代码如下:
```
<Context>
<Environment name="tjndi" value="hello JNDI" type="java.lang.String" />
</Context>
```
>< EnviTonment >元素用于配置命名的值, 所配置的值作为环境条目资源, 对整个 Web 应用可见。它包含的属性:name、type、value;
-
name:环境条目的名称,相对于 java:comp/env 的名称;
-
type: 环境条目的 Java 类名的全称;
-
value: 通过JNDI context 请求时,返回给应用的参数值,该值必须转换成 type 属性定义Java 类型;
2. 编写 JSP 代码 , 通过 JNDI 访问环境条目,代码如下:
<body>
<%@ page import="javax.naming.*" %>
<%
//javax.naming.Context提供了查找JNDI Resource的接口
Context ctx = new InitialContext(); //初始化Context对象
//java:comp/env/为前缀
String testjndi = (String) ctx.lookup("java:comp/env/tjndi"); //调用lookup()方法
out.print("test jndi:" + testjndi);
%>
</body>
-
java. naming包下的Context 接口表示命名上下文,它由一组名称到对象的绑定组成。
-
InitialContext是 Context接口的实现类;
-
Object lookup(String name) 方法根据名称检索指定对象,
-
为了避免 JNDI命名空间中的资源名称互相冲突. 并且避免可移植性问题 Java EE 应用程序中的所有名称应该以字串“java:comp/env”作为前缀;在上面的示例中:前缀后面的 'tjndi " 则对应着 context. xml 文件中< EnviTonment >元素的 name 属性;
使用JNDI的步骤
-
配置资源;
-
通过 Context 的 lookup()方法查找资源;
使用application 应该也能满足上述需求,但是 application 对象只能个 Web 应用程序中使用;使用 JNDI 发布的信息是对服务器上所有的 Web 应用程序都可见的,JNDI不只完成这种简单的需求,它还提供了对其他资源的引用;
数据库连接池
连接池(Connection Pool)
对于一个简单的数据库应用,由于对于数据库的访问不是很频繁。这时可以简单地在需要访问数据库时,就新创建一个连接,用完后就关闭它,这样做也不会带来什么明显的性能上的开销。但是对于一个复杂的数据库应用,情况就完全不同了。频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。
什么是连接池
1. 统数据库连接技术
-
需要经常与数据库建立连接,在访问结束后必须关闭连接释放资源;
-
当并发访问数量较大时,执行速度受到极大影响;
-
系统的安全性和稳定性相对较差;
连接池(Connection Pool)
数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。
数据库连接池:数据库连接池负责分配、管理和释放数据库连接;
-
它允许应用程序重复使用一个现有的数据连接,而不再是重新建立一个;
-
释放那些空闲时间超过最大空闲时间的数据库连接,以避免由于有释放数据库连接而引起的数据库连接泄露;
-
明显提高数据库的操作性能
接池原理
数据库连接池在初始化时将创建一定数量的数椐库连并放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接否被使用,连接池都将确保至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求被加入等待队列中;
连接池是如何管理连接的?
对于连接的管理可使用空闲池,即把巳经创建但尚未分配出去的连接存放到一个空闲池中;每当用户请求一个连接时,系统首先检查空闲池内有没有空闲连接,如果有就分配一个连接给用户;如果没有则检查当前连接池是否达到连接池所允许的最大连接数。如果没有达到,就新建一个连接。如杲已经达到,就等待一定的间。如果在等待的时间内有连接被释放出来,就可以把这个连接分配给等待的用户;如果等待时间超过预定时间,则返回空值 (null),系统对已经分配出去正在使用的连接只做计数,当使用完后再返还给空闲池;
数据库连接池技术带来的优势
- 资源重用
- 更快的系统响应速度
- 据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。
- 统一的连接管理,避免数据库连接泄漏
数据源与连接池
1. 数据源
- 数据源是在 JDBC 2. 0中引入的一个概念,在 JDBC 扩展包中定义了 javax.sql .DataSource 接口,它有一组特性用于确定和描述它所表示的现实存在的数据源,配置好的数据库连接池也是DataSource 的形式存在,其实现类负责建立与数据库的连接,在应用程序中访问数据库时不必编写接数据库的代码,可以直接从数据源获得数据库连接;
- 在 DataSource 中事先建立多个数据库连接, 这些数据库连接保存在座接池中。Java 程序访问数锯库时只需从连接池中取出空闲状态的数据库连接,当程序访问数据库结束时,再将数据库连接返回给接池. 这样做可以提高访问数据库的效率
数据源与JNDI资源
-
DataSource对象由Web容器(Tomcat)提供,因此不能在程序中创建实例的方法生成DateSource 对象而需要JNDI来获取
-
通过javax.naming.Context 的lookup()方法查找 JNDI Resource 的接口;
//初始化上下文 Context ctx =new InitialContext(); //获取与逻辑名相关联的数据源对象 DataSource ds=(DateSources)ctx.lookup("java:comp/env/jdbc/news”);
-
得到DateSource对象后,可以通过 DataSource 的getConnection ( ) 方法来获得数据库连接对象;
Connection conn=ds.getConnection();
-
当程序结束数据库访问后,应该调用 Connection 的 close ( ) 方法及时将 Connection 返回给数据连接池 . 使 Comection 恢复空闲状态;
数据源的配置
连接池实现数据库连接
1. context.xml
Tomcat的conf/context.xml文件的配置。上面JNDI时学习了如何在 context . xml 文件中增加`<Environment>`元素配置公共资源,而配数据源时需在`<Context>`节点下添加`<Resource>`元素。
<Context>
<Resource name="jdbc/news" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000" username="newsu"
password="123456" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/newsmanagersystem?
useUnicode=true&characterEncoding=utf-8" />
</Context>
注意:对于url中出现的“&”,应替换为对应的实体“&
”
- 不同的Web 服务器,配置数据源的方式一样的,需要根据服务器提供的助文档进行配置。
2. 配置web.xml文件
把数据库驱动jar文件,加入到Tomcat的lib中。在web.xml中配置`<resource-ref>`
<web-app>
<resource-ref>
<description>news DataSource</ description >
// jdbc/news:指定JNDI的名字,与<Resource>元素中的name一致
<res-ref-name>jdbc/news</res-ref-name>
// javax.sql.DataSource:指定引用资源的类名,与<Resource>元素中的type一致
<res-type>javax.sql.DataSource</res-type>
// Container:指定管理所引用资源的Manager与<Resource>元素中的auth一致
<res-auth>Container</res-auth>
</resource-ref>
< /web-app >
<resource-ref>
元素包含一个对外部资源的引用,它包含一个可选的description、一个引用资源的名称(相对于java:comp/env环境的JDNI名)、资源类型、验证方式;
4. 查找并使用lookup()方法获取数据源对象
总结
- 配置context.xml文件
- 配置web.xml文件
- 添加数据库驱动
- 编写代码,使用lookup()方法获得数据对象
常见错误
-
误提示: Cannot load JDBC driVer class (不能加载驱动类);
错误原因及解决方案:通过数据源访问数据库,数据源由 Tomcat创建 , 应该把 JDBC 驱程序的 jar 文件复制到 Tomcat 的 jib 目录下;
-
常见错误Cannot create JDBC driver of class ‘ ’ for connect URL ‘null’ (由于连接路径为null. 不能创建驱动 );
错误原因及解决方案 : 此类错误多在数椐库驱动或者在连接错误时出现,解决的方法是检查 context . xml 文件中数据源配置的文件信息,确保配置信息完全正确;
-
错误信息:Name [news] is not bound in this Context (jdbc 名称没有绑定到当前上下文)
在使用lookup()方法查找数据源时,如果数据源名称与配置中的名称不一致,则程序运时会报此错误。解决方法是确保context. xml 文件中指定的数据源名称与代码中所要访问数据源名称一致;在程序中调用 lookup()方法查找数据源时,没有使用前缀 (java:comp/env/) +数据源名称,则程序运行时会报此错误。解决方法是在使用 lookup()查找数据源时, 使用前缀(java:comp/env/) +数据源名称的形式;
软件设计分层架构
三层架构
三层指:表示层,业务逻辑层,数据访问层
- 表示层
表示层:位于最外层 ( 最上层 ),使用户能够直接访问,用于显示数据和接收用户输入的数据,为用户提供一种交互式操作界面。在 Web 应用程序中,表示层一般以 JSP 文件、HTML文件为主。 - 业务逻辑层
业务逻辑层:其主要功能是提供对业务逻辑处理的封装,在业务逻辑层中,通常会定义些接口,表示层通过调用业务逻辑层的接口实现各种操作,如数据有效性的检验. 业务辑描述等相关功能,业务逻辑层经常放在 service 包或 biz 包下,btz 是英文 buslness 的缩写,意思是 ‘业务逻辑’。 - 数据访问层
数据访问层:该层实现对数据的保存和读取操作。数据访问,可以访问关系数椐库、文件或 XML 文档等。数据访问层通常放在 dao 包下,DAO 是英文 Data Access Object 的缩写,意思是 "数据访问对象。
层与层之间的关系
在三层架构中各层之间相互依赖。表示层依赖于业务逻辑层,业务逻辑层依赖于数据访层 ,各层之间的数据传递方向分为请求与晌应两个方向。
分层的原则
- 上一层依赖其下一层、依赖关系不跨层
上一层调用下一层所得到的执行结果完全取决于下一层中的代码实现,上一层无法进行控; - 下一层不能调用上一层
上一层调用下一层功能,下一层不能调用上一层功能。下一层为上一层提供服务,而不使用上一层提供的服务; - 下一层不依赖上一层
下一层的代码实现决定了上一层获得的内容,所以说上一层依赖下一层,从另一个角度来说,上一层不管如何发生改变. 对于其调用下一层的业务是不会发生变化的,因此对于下一层来说,上一层的改变不会对其产生任何影响; - 在上一层中不能出现下一层的概念
使用分层架构的一个优点是在系统中各个功能分工明确,在某一层中不会出现其下一层的任内容,简单地说就是在业务逻辑层中. 只能有用于业务逻辑控制的代码,而不能出现数据库访问层中才有的 SQL 语句 , 确保层次间的关系很清晰。
使用三层架构开发的特点和优势
分层的 特点
-
下层不知上层的存在。
-
每一层仅知它下一层的存在,而不知另外的下层。
-
上层使用下层提供的服务,并为下层提供数据。
分层思想:就是指这样一种分工,它将系统按不同职责组织成有序的层次。其中,除最上层外,每一层仅提供若干服务供其相邻的上层使用,但不知上层的存在;除了最下层外,每一层仅调用其临近下层的服务。
分层的 优点
-
职责划分清晰;
由于某一层仅仅调用其相邻下一层所提供的服务, 所以,只要本层的实现和相邻下一层的实现定义完整,开发人员在开发某一层时就可以将关注集中于这一层所用的思想、模式、技术,而无需关心其他层的具体实现; -
利用面向对象的特性迸行无损替换;
-
复用代码;
例如:铁路局制作发布了一个 “ Business Service’ , 用于提供火车车次预告信息,这样火车票代售网站就可以利用这个服务层提供的服务制作火车票信息页面,而无须再重新实现获取信息的功能; -
降低了系统内部的依赖程度:
例如:在三层架构中,表示层只与业务逻辑层联系,而对业务逻辑层下还有哪些层并不关心,表示层只依赖于业务逻辑;
分层的弊端
-
例如,原本很直接的操作,现在要通过层层传递,势必造成性能的下降;
-
另外,虽然分层架构可以降低层内变化的成本,但对于功能定义 (接口定义)变化非常敏感;功能定义的变动对于分层架构是致命的,修改起来难度非常大。所以,一个简单的判断法则是,如果系统层内实现频繁变动 (甚至整层替换) 的可能性很大,而功能定义变动的可性很小,就使用分层;
三层开发的优势包括松耦合、重用性高、生命周期成本低、可维护性高。
三层分别为:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)。
分层的作用
-
解耦。
-
简化复杂问题。
-
便于系统维护/升级。
-
逻辑复用。
-
便于团队开发。
-
方便部署。