一、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
-
- @Component
-
- 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(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);
-
-
-
-
-
-
-
- }
-
- }
上面是较为常用的注解。
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的反射机制和动态代理实现这一点并不难。
我们为上边的计算器,扩展 两个应用:计算最大值和最小值,他们分别是两接口和对应的实现类“ M ax Calculator ”(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简单些,在此也不多做介绍了。