Posted on 2010-01-26 22:49
長城 閱讀(373)
評論(0) 編輯 收藏
這知識越學越簡單了。其實現在學習的Spring和之前學習的Hibernate等框架等,他們的實現都是我們之前學習的Java基礎和JavaWeb基礎。再加之做了幾個總結性的練習,鞏固了基礎。所以現在學習起來就比較容易了。
今日的課程內容為兩部分:Spring中的AOP面向切面編程和Spring對JDBC的支持。
一、Spring-AOP
AOP面向切面編程(Aspect-Oriented Programming),是對傳統OOP的補充。AOP使用是使用動態代理實現的。動態代理我們已經非常熟悉了。我也將逐漸的由實現原理轉向應用,因為我們在學習JavaWEB基礎的時候,原理已經學習過了。
AspectJ是Java社區里最完整最流行的AOP框架,Spring2.X使用的正是這個框架。AspectJ已經被廣泛應用,她具有大好前程。
AspectJ支持注解和XML配置。
1.啟用AspectJ注解支持
1).AspectJ需要兩個Jar包:spring-framework-2.5.6.SEC01\lib\aspectj\目錄下“aspectjrt.jar”和“aspectjweaver.jar”。
2).在Bean配置文件中添加“<aop:aspectj-autoproxy/>”。
2.使用AspectJ注解聲明切面
AspectJ 支持 5 種類型的通知注解:
1) @Before: 前置通知, 在方法執行之前執行。
2) @After: 后置通知, 在方法執行之后執行 。
3) @AfterRunning: 返回通知, 在方法返回結果之后執行。
4) @AfterThrowing: 異常通知, 在方法拋出異常之后。
5) @Around: 環繞通知, 圍繞著方法執行。
我們來看個簡單的例子,算術計算器。
1).定義一個接口:
package cn.itcast.cc.spring.aspectj; public interface ArithmeticCalculator { void add(int i, int j);// 無返回值,用于測試 void sub(int i, int j);// 無返回值,用于測試 int mul(int i, int j); int div(int i, int j); } |
2).實現類:
package cn.itcast.cc.spring.aspectj; import org.springframework.stereotype.Component; @Component(value="calc") public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override public void add(int i, int j) { int result = i + j; System.out.println(result); } @Override public void sub(int i, int j) { int result = i - j; System.out.println(result); } @Override public int div(int i, int j) { int result = i / j; return result; } @Override public int mul(int i, int j) { int result = i * j; return result; } } |
3).AspectJ切面類:
package cn.itcast.cc.spring.aspectj; import org.aspectj.lang.*; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Aspect // AspectJ切面Bean @Component // Bean public class ArithmeticCalculatorAspect { // 前置通知 @Before(value = "execution (* cn.itcast.cc.spring.aspectj.ArithmeticCalculator.* (..))") public void beforeMethodLoggin(JoinPoint jp) { System.out.println("before " + jp.getSignature().getName()); } // 后置通知 @After(value = "execution (* cn.itcast.cc.spring.aspectj.ArithmeticCalculator.* (..))") public void afterMethodLoggin(JoinPoint jp) { System.out.println("after " + jp.getSignature().getName()); } // 返回通知 @AfterReturning(value = "pointCut()", returning = "result") public void afterMethodLogginReturn(JoinPoint jp, Object result) { System.out.println("after " + jp.getSignature().getName() + " return " + result); } // 異常通知 @AfterThrowing(value = "pointCut()", throwing = "e") public void errorMethodLoggin(JoinPoint jp, Throwable e) { System.out.println("method " + jp.getSignature().getName() + " throwing " + e); } // 環繞通知,通過它可以實現上面所有的通知。 @Around("execution (* cn.itcast.cc.spring.aspectj.ArithmeticCalculator.* (..))") public Object aroundMethodLoggin(ProceedingJoinPoint pjp) { System.out.println("around_before " + pjp.getSignature().getName()); Object result = null; try { result = pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); System.out.println("around_error " + pjp.getSignature().getName()); } System.out.println("around_after " + pjp.getSignature().getName()); System.out.println("around_after " + pjp.getSignature().getName() + " return " + result); return result; } // 重用切入點,其他“通知方法”可以引用此方法名稱“pointCut()”。 @Pointcut(value = "execution (* cn.itcast.cc.spring.aspectj.ArithmeticCalculator.* (..))") public void pointCut() { } } |
4).Bean配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="cn.itcast.cc.spring.aspectj" /> <aop:aspectj-autoproxy /> </beans> |
5).測試類:
package cn.itcast.cc.spring.aspectj; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("beans-aspect.xml"); ArithmeticCalculator calc = (ArithmeticCalculator) ac.getBean("calc"); calc.add(1, 2); // calc.sub(2, 1); // calc.mul(3, 3); // calc.div(10, 2); } } |
上面是較為常用的注解。
2.使用XML文件聲明切面
使用XML文件聲明切面沒有使用注解聲明切面直觀,簡單。
1).刪除所有AspectJ注解
2).xml配置文件內容為:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="arithmeticCalculatorAspect" class="cn.itcast.cc.spring.xml.ArithmeticCalculatorAspect" /> <bean id="arithmeticCalculatorImpl" class="cn.itcast.cc.spring.xml.ArithmeticCalculatorImpl" /> <aop:config> <aop:pointcut expression="execution(* cn.itcast.cc.spring.xml.ArithmeticCalculator.* (..))" id="pointcut" /> <aop:aspect order="1" ref="arithmeticCalculatorAspect"> <aop:before method="beforeMethodLoggin" pointcut-ref="pointcut"/> <aop:after method="afterMethodLoggin" pointcut-ref="pointcut"/> <aop:after-returning method="afterMethodLogginReturn" returning="result" pointcut-ref="pointcut"/> <aop:after-throwing method="errorMethodLoggin" throwing="e" pointcut-ref="pointcut"/> <aop:around method="aroundMethodLoggin" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans> |
3.引入通知
這是一個高級應用。我們知道Java只能單繼承,使用這個引入通知就能實現多集成!這一點是我沒想到的,但想一想Java的反射機制和動態代理實現這一點并不難。
我們為上邊的計算器,擴展兩個應用:計算最大值和最小值,他們分別是兩接口和對應的實現類“MaxCalculator”(Impl)和“MinCalculator”(Impl)。
使用注解的方式實現引入通知,在ArithmeticCalculatorAspect.java中添加:
@DeclareParents(value="cn.itcast.cc.spring.aspectj.ArithmeticCalculator*", defaultImpl=MinCalculatorImpl.class) public MinCalculator minCalculator; @DeclareParents(value="cn.itcast.cc.spring.aspectj.ArithmeticCalculator*", defaultImpl=MaxCalculatorImpl.class) public MaxCalculator maxCalculator; |
使用XML文件實現引入通知:
<aop:declare-parents types-matching="cn.itcast.cc.spring.xml.ArithmeticCalculator*" implement-interface="cn.itcast.cc.spring.xml.MaxCalculator" default-impl="cn.itcast.cc.spring.xml.MaxCalculatorImpl"/> <aop:declare-parents types-matching="cn.itcast.cc.spring.xml.ArithmeticCalculator*" implement-interface="cn.itcast.cc.spring.xml.MinCalculator" default-impl="cn.itcast.cc.spring.xml.MinCalculatorImpl"/> |
引入通知的使用:
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-xml.xml"); Object obj = ctx.getBean("calc"); ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) obj; // 可以轉換 MinCalculator minCalculator = (MinCalculator) obj; // 可以轉換 MaxCalculator maxCalculator = (MaxCalculator) obj; |
二、Spring-JDBC
JDBC中Spring中似乎比較常用,但使用起來非常簡單。
1.引入數據源
昨天介紹的使用外部Bean正是引入C3P0數據源的方法,在此我們就不重復了。
2.使用方式
我們使用spirng為我們提供的一個CURD操作類——JdbcTemplate,在xml配置文件中添加一個Bean:
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> |
在程序中使用:
package cn.itcast.cc.spring.jdbc; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; public class JdbcTest { private ApplicationContext ac = new ClassPathXmlApplicationContext( "beans.xml"); private JdbcTemplate jdbcTemplate = (JdbcTemplate) ac .getBean("jdbcTemplate"); @Test public void testInsert() { String sql = "insert into customers(customer_name,home_address,mobile_phone) VALUES (?,?,?)"; Object[] args = { "changcheng", "DaLian", "1398639955" }; this.jdbcTemplate.update(sql, args); } } |
在此我只列出了insert的方法,其他方法可以查看Spring手冊,十分簡單。
Spring還為我們提供了一個更簡單的CURD類——SimpleJdbcTemplate,它使用起來比JdbcTemplate簡單些,在此也不多做介紹了。
整體上內容比較簡單,目前還沒有將Spring實際應用到項目中。明天是Spring的最后一天,接下來就是佟佟的教育辦公管理系統。我想會使用到Spring的,這個項目很重要,一定要搞好!