代理模式的作用:
爲其他對象提供一種代理以控制對這個對象的訪問。(在某些情況下,一個客戶不想或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用)
l 抽象角色:聲明真實對象和代理對象的公共接口。
l 代理角色:代理對象角色內部含有對真實對象的引用,從而可以操作真是對象,同時代理對象提供與真實對象相同的接口以便在任何時刻都能代替真實對象。同時,代理對象可以在執行真實對象操作時,附加其他的操作,相當於對真實對象進行封裝。
l 真實角色:代理角色所代表的真實對象,是我們要真正要引用的對象。
Java動態代理類位於Java.lang.reflect包下,一般主要涉及到以下兩個類:
(1) InvocationHandler接口,是代理實例的調用處理程序實現的接口。 它只有一個方法:invoke(Object proxy, Method method, Object[] args)。我們需要在實現InvocationHandler接口的具體類中的invoke方法內,編寫代理行爲的具體邏輯。然後將這個InvocationHandler對象傳遞給Proxy類中生成一個動態的代理對象。
(2) Proxy 類,提供用於創建動態代理類和實例的靜態方法。其最重要的兩個靜態創建方法:
Static Class getProxyClass (ClassLoader loader, Class[] interfaces):獲得一個代理類,其中loader是類裝載器,interfaces是真實類所擁有的全部接口的數組。
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理類的一個實例,返回後的代理類可以當作被代理類使用(可使用被代理類的在Subject接口中聲明過的方法)。
invoke Object invoke(Objectproxy, Methodmethod, Object[] args) throws Throwable
在代理實例上處理方法調用並返回結果。在與方法關聯的代理實例上調用方法時,將在調用處理程序上調用此方法。
參數:
proxy - 在其上調用方法的代理實例
method - 對應於在代理實例上調用的接口方法的 Method 實例。Method 對象的聲明類將是在其中聲明方法的接口,該接口可以是代理類賴以繼承方法的代理接口的超接口。
args - 包含傳入代理實例上方法調用的參數值的對象數組,如果接口方法不使用參數,則爲 null。基本類型的參數被包裝在適當基本包裝器類(如 java.lang.Integer 或 java.lang.Boolean)的實例中。
返回:
從代理實例的方法調用返回的值。如果接口方法的聲明返回類型是基本類型,則此方法返回的值一定是相應基本包裝對象類的實例;否則,它一定是可分配到聲明返回類型的類型。如果此方法返回的值爲 null 並且接口方法的返回類型是基本類型,則代理實例上的方法調用將拋出 NullPointerException。否則,如果此方法返回的值與上述接口方法的聲明返回類型不兼容,則代理實例上的方法調用將拋出 ClassCastException。
DBCP
DBCP(DataBase connection pool),數據庫連接池。是 apache 上的一個 java 連接池項目,也是 tomcat 使用的連接池組件。單獨使用dbcp需要3個包:
common-dbcp.jar,
common-pool.jar
,common-collections.jar
由於建立數據庫連接是一個非常耗時耗資源的行爲,所以通過連接池預先同數據庫建立一些連接,放在內存中,應用程序需要建立數據庫連接時直接到連接池中申請一個就行,用完後再放回去。
操作步驟
1、賦值jar包及dbconfig.properties文件
2、修改配置文件
3、 修改DBManager文件
a) 靜態初始化塊,加載配置文件
b) DataSource ds =
BasicDataSourceFactory.createDataSource(prop);
c) 修改getConnection()
- public static Connection getConnection() throws SQLException{
- return ds.getConnection();
- }
3、在數據庫操作中任然使用DBManager的getConnection和release方法即可
C3P0
C3P0是一個開源的JDBC連接池,它實現了數據源和JNDI綁定,支持JDBC3規範和JDBC2的標準擴展。目前使用它的開源項目有Hibernate,Spring等。
1、 複製jar文件
c3p0-0.9.2-pre1.jar
mchange-commons-0.2.jar
2、 創建DBManager_c3p0
- ds = new ComboPooledDataSource();
- ds.setDriverClass("com.mysql.jdbc.Driver");
- ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
- ds.setUser("root");
- ds.setPassword("admin");
- ds.setInitialPoolSize(20);
- ds.setMaxPoolSize(40);
- ds.setMinPoolSize(10);
3、 測試代碼
解決c3p0配置問題
1、 在src目錄下創建c3p0-config.xml文件,在c3p0文檔中找到配置文件案例代碼複製到xml中,格式化代碼。
2、 修改xml文件,添加driverClass, jdbcUrl, user, password四個屬性如下
- <c3p0-config>
- <default-config>
- <property name="automaticTestTable">con_test</property>
- <property name="checkoutTimeout">30000</property>
- <property name="idleConnectionTestPeriod">30</property>
- <property name="initialPoolSize">10</property>
- <property name="maxIdleTime">30</property>
- <property name="maxPoolSize">100</property>
- <property name="minPoolSize">10</property>
- <property name="maxStatements">200</property>
- </default-config>
- <named-config name="mysql">
- <property name="driverClass">com.mysql.jdbc.Driver</property>
- <property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
- <property name="user">root</property>
- <property name="password">admin</property>
- <property name="acquireIncrement">5</property>
- <property name="initialPoolSize">10</property>
- <property name="minPoolSize">5</property>
- <property name="maxPoolSize">30</property>
- </named-config>
- </c3p0-config>
3、 修改DBManager_c3p0
- try{
- ds = new ComboPooledDataSource("mysql");
- }catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
4、 測試代碼
dbcp沒有自動的去回收空閒連接的功能
c3po有自動回收空閒連接功能
JNDI
JNDI(Java Naming and Directory Interface,Java命名和目錄接口)是一組在Java應用中訪問命名和目錄服務的API。命名服務將名稱和對象聯繫起來,使得我們可以用名稱訪問對象。目錄服務是一種命名服務,在這種服務裏,對象不但有名稱,還有屬性。
配置JNDI
(tomcat文檔中有說明和案例,可以打開localhost:8080查看)
l 途徑一:
在tomcat服務器的server.xml文件中過的host中加入<context> …</context>
- <Context path=” /DataSource_JNDI_Test”
- docBase=”webapps/DataSource_JNDI_Test”>
- <Resource name="jdbc/TestDB"
- auth="Container"
- type="javax.sql.DataSource"
- driverClassName="com.mysql.jdbc.Driver"
- url="jdbc:mysql://localhost:3306/test"
- username="root"
- password="admin"
- maxActive="8"
- maxIdle="4"/>
- </Context>
l 途徑二:
在web工程中的添加context.xml文件
步驟
1、 在myecipse的web項目的META-INF目錄下創建context.xml,內容如下:
- <Context>
- <Resource name="jdbc/TestDB"
- auth="Container"
- type="javax.sql.DataSource"
- driverClassName="com.mysql.jdbc.Driver"
- url="jdbc:mysql://localhost:3306/test"
- username="root"
- password="admin"
- maxActive="8"
- maxIdle="4"/>
- </Context>
2、 加載連接池,代碼如下
- //初始化jndi容器
- Context initCtx = new InitialContext();
- //檢索出jndi容器Context envCtx = (Context) initCtx.lookup("java:comp/env");
- //從容器中找到連接池
- DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB");
- conn = ds.getConnection();
- …
- conn.close();
3、 將mysql的驅動包複製到tomcat的lib目錄下
4、 啓動服務器,測試