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).定义一个接口:


Java代码  收藏代码
  1. package cn.itcast.cc.spring.aspectj;  
  2.   
  3. public interface ArithmeticCalculator {  
  4.   
  5. void add(int i, int j);// 无返回值,用于测试  
  6.   
  7. void sub(int i, int j);// 无返回值,用于测试  
  8.   
  9. int mul(int i, int j);  
  10.   
  11. int div(int i, int j);  
  12.   
  13. }  
 

2) .实现类:


Java代码  收藏代码
  1. package cn.itcast.cc.spring.aspectj;  
  2.   
  3. import org.springframework.stereotype.Component;  
  4.   
  5. @Component(value="calc")  
  6.   
  7. public class ArithmeticCalculatorImpl implements ArithmeticCalculator {  
  8.   
  9. @Override  
  10.   
  11. public void add(int i, int j) {  
  12.   
  13. int result = i + j;  
  14.   
  15. System.out.println(result);  
  16.   
  17. }  
  18.   
  19. @Override  
  20.   
  21. public void sub(int i, int j) {  
  22.   
  23. int result = i - j;  
  24.   
  25. System.out.println(result);  
  26.   
  27. }  
  28.   
  29. @Override  
  30.   
  31. public int div(int i, int j) {  
  32.   
  33. int result = i / j;  
  34.   
  35. return result;  
  36.   
  37. }  
  38.   
  39. @Override  
  40.   
  41. public int mul(int i, int j) {  
  42.   
  43. int result = i * j;  
  44.   
  45. return result;  
  46.   
  47. }  
  48.   
  49. }  
 

3) .AspectJ切面类:


Java代码  收藏代码
  1. package cn.itcast.cc.spring.aspectj;  
  2.   
  3. import org.aspectj.lang.*;  
  4.   
  5. import org.aspectj.lang.annotation.*;  
  6.   
  7. import org.springframework.stereotype.Component;  
  8.   
  9. @Aspect // AspectJ切面Bean  
  10.   
  11. @Component // Bean  
  12.   
  13. public class ArithmeticCalculatorAspect {  
  14.   
  15. // 前置通知  
  16.   
  17. @Before(value = "execution (* cn.itcast.cc.spring.aspectj.ArithmeticCalculator.* (..))")  
  18.   
  19. public void beforeMethodLoggin(JoinPoint jp) {  
  20.   
  21. System.out.println("before " + jp.getSignature().getName());  
  22.   
  23. }  
  24.   
  25. // 后置通知  
  26.   
  27. @After(value = "execution (* cn.itcast.cc.spring.aspectj.ArithmeticCalculator.* (..))")  
  28.   
  29. public void afterMethodLoggin(JoinPoint jp) {  
  30.   
  31. System.out.println("after " + jp.getSignature().getName());  
  32.   
  33. }  
  34.   
  35. // 返回通知  
  36.   
  37. @AfterReturning(value = "pointCut()", returning = "result")  
  38.   
  39. public void afterMethodLogginReturn(JoinPoint jp, Object result) {  
  40.   
  41. System.out.println("after " + jp.getSignature().getName() + " return " + result);  
  42.   
  43. }  
  44.   
  45. // 异常通知  
  46.   
  47. @AfterThrowing(value = "pointCut()", throwing = "e")  
  48.   
  49. public void errorMethodLoggin(JoinPoint jp, Throwable e) {  
  50.   
  51. System.out.println("method " + jp.getSignature().getName()  
  52.   
  53. " throwing " + e);  
  54.   
  55. }  
  56.   
  57. // 环绕通知,通过它可以实现上面所有的通知。  
  58.   
  59. @Around("execution (* cn.itcast.cc.spring.aspectj.ArithmeticCalculator.* (..))")  
  60.   
  61. public Object aroundMethodLoggin(ProceedingJoinPoint pjp) {  
  62.   
  63. System.out.println("around_before " + pjp.getSignature().getName());  
  64.   
  65. Object result = null;  
  66.   
  67. try {  
  68.   
  69. result = pjp.proceed();  
  70.   
  71. catch (Throwable e) {  
  72.   
  73. e.printStackTrace();  
  74.   
  75. System.out.println("around_error " + pjp.getSignature().getName());  
  76.   
  77. }  
  78.   
  79. System.out.println("around_after " + pjp.getSignature().getName());  
  80.   
  81. System.out.println("around_after " + pjp.getSignature().getName()  
  82.   
  83. " return " + result);  
  84.   
  85. return result;  
  86.   
  87. }  
  88.   
  89. // 重用切入点,其他 “通知方法”可以引用此方法名称“pointCut()”。  
  90.   
  91. @Pointcut(value = "execution (* cn.itcast.cc.spring.aspectj.ArithmeticCalculator.* (..))")  
  92.   
  93. public void pointCut() {  
  94.   
  95. }  
  96.   
  97. }  
 

4) .Bean配置文件:


Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <beans xmlns="http://www.springframework.org/schema/beans"  
  4.   
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
  6.   
  7. xmlns:context="http://www.springframework.org/schema/context"  
  8.   
  9. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  10.   
  11. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd  
  12.   
  13. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
  14.   
  15. <context:component-scan base-package="cn.itcast.cc.spring.aspectj" />  
  16.   
  17. <aop:aspectj-autoproxy />  
  18.   
  19. </beans>  
 

5).测试类:


Java代码  收藏代码
  1. package cn.itcast.cc.spring.aspectj;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4.   
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  6.   
  7. public class Main {  
  8.   
  9. public static void main(String[] args) {  
  10.   
  11. ApplicationContext ac = new ClassPathXmlApplicationContext("beans-aspect.xml");  
  12.   
  13. ArithmeticCalculator calc = (ArithmeticCalculator) ac.getBean("calc");  
  14.   
  15. calc.add(12);  
  16.   
  17. // calc.sub(2, 1);  
  18.   
  19. // calc.mul(3, 3);  
  20.   
  21. // calc.div(10, 2);  
  22.   
  23. }  
  24.   
  25. }  
 

上面是较为常用的注解。

 

2.使用XML文件声明切面

使用XML文件声明切面没有使用注解声明切面直观,简单。

1) .删除所有AspectJ注解

2) .xml配置文件内容为:


Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <beans xmlns="http://www.springframework.org/schema/beans"  
  4.   
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
  6.   
  7. xmlns:context="http://www.springframework.org/schema/context"  
  8.   
  9. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  10.   
  11. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd  
  12.   
  13. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
  14.   
  15. <bean id="arithmeticCalculatorAspect" class="cn.itcast.cc.spring.xml.ArithmeticCalculatorAspect" />  
  16.   
  17. <bean id="arithmeticCalculatorImpl" class="cn.itcast.cc.spring.xml.ArithmeticCalculatorImpl" />  
  18.   
  19. <aop:config>  
  20.   
  21. <aop:pointcut  
  22.   
  23. expression="execution(* cn.itcast.cc.spring.xml.ArithmeticCalculator.* (..))"  
  24.   
  25. id="pointcut" />  
  26.   
  27. <aop:aspect order="1" ref="arithmeticCalculatorAspect">  
  28.   
  29. <aop:before method="beforeMethodLoggin" pointcut-ref="pointcut"/>  
  30.   
  31. <aop:after method="afterMethodLoggin" pointcut-ref="pointcut"/>  
  32.   
  33. <aop:after-returning method="afterMethodLogginReturn" returning="result" pointcut-ref="pointcut"/>  
  34.   
  35. <aop:after-throwing method="errorMethodLoggin" throwing="e" pointcut-ref="pointcut"/>  
  36.   
  37. <aop:around method="aroundMethodLoggin" pointcut-ref="pointcut"/>  
  38.   
  39. </aop:aspect>  
  40.   
  41. </aop:config>  
  42.   
  43. </beans>  
 

3.引入通知

这是一个高级应用。我们知道Java只能单继承,使用这个引入通知就能实现多集成! 这一点是我没想到的,但想一想Java的反射机制和动态代理实现这一点并不难。

 

我们为上边的计算器,扩展 两个应用:计算最大值和最小值,他们分别是两接口和对应的实现类“ M ax Calculator ”(Impl)和“MinCalculator ”(Impl)。

 

使用注解的方式实现引入通 知,在 ArithmeticCalculatorAspect .java中添加 :


Java代码  收藏代码
  1. @DeclareParents(value="cn.itcast.cc.spring.aspectj.ArithmeticCalculator*",  
  2.   
  3. defaultImpl=MinCalculatorImpl.class)  
  4.   
  5. public MinCalculator minCalculator;  
  6.   
  7. @DeclareParents(value="cn.itcast.cc.spring.aspectj.ArithmeticCalculator*", defaultImpl=MaxCalculatorImpl.class)  
  8.   
  9. public MaxCalculator maxCalculator;  
 

使用XML文件实现引入通 知:


Xml代码  收藏代码
  1. <aop:declare-parents types-matching="cn.itcast.cc.spring.xml.ArithmeticCalculator*"   
  2.   
  3. implement-interface="cn.itcast.cc.spring.xml.MaxCalculator"  
  4.   
  5. default-impl="cn.itcast.cc.spring.xml.MaxCalculatorImpl"/>  
  6.   
  7. <aop:declare-parents types-matching="cn.itcast.cc.spring.xml.ArithmeticCalculator*"   
  8.   
  9. implement-interface="cn.itcast.cc.spring.xml.MinCalculator"  
  10.   
  11. default-impl="cn.itcast.cc.spring.xml.MinCalculatorImpl"/>  
 

引入通知的使用:


 

Java代码  收藏代码
  1. ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-xml.xml");  
  2.   
  3. Object obj = ctx.getBean("calc");  
  4.   
  5. ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) obj;  
  6.   
  7. // 可以转换  
  8.   
  9. MinCalculator minCalculator = (MinCalculator) obj;  
  10.   
  11. // 可以转换  
  12.   
  13. MaxCalculator maxCalculator = (MaxCalculator) obj;  
 

 

二、Spring-JDBC

JDBC中Spring中似乎比较常用,但使用起来非常简单。

 

1.引入数据源

昨天介绍的使用外部Bean正是引入C3P0数据源的方法,在此我们就不重复了。

 

2.使用方式

我们使用spirng为我们提供的一个CURD操作类——JdbcTemplate,在xml配置文件中添加一个Bean:


Xml代码  收藏代码
  1. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
  2.   
  3. <property name="dataSource" ref="dataSource"/>  
  4.   
  5. </bean>  
 

在程序中使用:


Java代码  收藏代码
  1. package cn.itcast.cc.spring.jdbc;  
  2.   
  3. import org.junit.Test;  
  4.   
  5. import org.springframework.context.ApplicationContext;  
  6.   
  7. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  8.   
  9. import org.springframework.jdbc.core.JdbcTemplate;  
  10.   
  11. public class JdbcTest {  
  12.   
  13. private ApplicationContext ac = new ClassPathXmlApplicationContext(  
  14.   
  15. "beans.xml");  
  16.   
  17. private JdbcTemplate jdbcTemplate = (JdbcTemplate) ac  
  18.   
  19. .getBean("jdbcTemplate");  
  20.   
  21. @Test  
  22.   
  23. public void testInsert() {  
  24.   
  25. String sql = "insert into customers(customer_name,home_address,mobile_phone) VALUES (?,?,?)";  
  26.   
  27. Object[] args = { "changcheng""DaLian""1398639955" };  
  28.   
  29. this.jdbcTemplate.update(sql, args);  
  30.   
  31. }  
  32.   
  33. }  
 

在此我只列出了insert的方法,其他方法可以查看Spring手册,十分简单。

 

Spring还为我们提供了一个更简单的CURD类—— SimpleJdbcTemplate , 它使用起来比 JdbcTemplate简单些,在此也不多做介绍了。

你可能感兴趣的:(java,spring,AOP,编程,xml,jdbc)