`

Spring中的AOP面向切面编程和Spring对JDBC的支持

    博客分类:
  • SSH
阅读更多

一、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的反射机制和动态代理实现这一点并不难。

 

我们为上边的计算器,扩展 两个应用:计算最大值和最小值,他们分别是两接口和对应的实现类“ 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简单些,在此也不多做介绍了。

1
0
分享到:
评论

相关推荐

    Spring框架 jar 架包 spring开发文档详解

    Spring BeanFactory Spring IOC(控制翻转)/DI(依赖注入) Spring Proxy Spring AOP 面向切面编程 Spring与JDBC整合 Spring声明式事务 Spring与Hibernate整合 Spring与Struts整合

    JAVA中spring介绍以及个人使用心得

    面向切面编程(AOP):Spring框架支持面向切面编程(AOP),可以将横切关注点(如日志记录、事务管理)与应用程序的业务逻辑分离,提高代码的模块化和可重用性。 数据访问:Spring框架提供了对各种数据访问技术的...

    Spring各项功能附代码全解析.docx

    Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架 为了解决企业应用开发的复杂性而创建 二 Spring功能 1. 方便解耦 简化开发 Spring就是一个大工厂 专门负责生成Bean 可以将所有对象创建和依赖关系维护...

    Spring插件安装图解

    面向切面编程(AOP --- aspect oriented programming) 容器: Spring 是一个容器, 因为它包含并且管理应用对象的生命周期 框架: Spring 实现了使用简单的组件配置组合成一个复杂的应用. 在 Spring 中可以使用 XML 和 ...

    77道Spring面试题以及参考答案(2024年最新版)

    这篇文章总结了77道Spring面试题及答案,涵盖了Spring的多个核心主题,包括Spring概述、Spring控制反转(IoC)、Spring Bean、Spring注解、Spring数据访问和Spring面向切面编程(AOP)等。文章对每个主题下的重点问题都给...

    spring4.0.zip

    面向切面编程(AOP — aspect oriented programming) 容器: Spring 是一个容器, 因为它包含并且管理应用对象的生命周期 框架: Spring 实现了使用简单的组件配置组合成一个复杂的应用. 在 Spring 中可以使用 XML 和 ...

    spring4.1核心包

    Spring面向切面编程,提供AOP实现。Spring Beans之上将横切关注点模块化 2. spring-aspects-4.1.1.RELEASE.jar 提供的对AspectJ框架的整合,也是A面向切面编程。 AspectJ可用于基于普通Java对象的模块化 注意:...

    spring2.5.chm帮助文档(中文版)

    2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.3.3. 对bean命名pointcut( bean name pointcut element)的支持 2.3.4. 对AspectJ装载时织入(AspectJ load-time weaving...

    Spring面试71题与答案

     面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。  容器:Spring包含并管理应用中对象的生命周期和配置。  MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的...

    全网最热spring问题总结.pdf

    面向切面的编程(AOP): Spring 支持面向切面的编程, 并且把应用业务 逻辑和系统服务分开。 容器: Spring 包含并管理应用中对象的生命周期和配置。 MVC 框架: Spring 的 WEB 框架是个精心设计的框架, 是 Web ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    6. 使用Spring进行面向切面编程(AOP) 6.1. 简介 6.1.1. AOP概念 6.1.2. Spring AOP的功能和目标 6.1.3. Spring的AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点...

    Spring+MVC+Mybatis 书城项目

    Spring提供了很多功能,包括事务管理、依赖注入、AOP(面向切面编程)等。 Spring MVC: Spring MVC是Spring框架的一个模块,它实现了MVC(模型-视图-控制器)设计模式,用于构建Web应用。Spring MVC允许你将应用的...

    Spring中文帮助文档

    6. 使用Spring进行面向切面编程(AOP) 6.1. 简介 6.1.1. AOP概念 6.1.2. Spring AOP的功能和目标 6.1.3. AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点...

    Spring学习笔记.zip

    Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control: 反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务...

    跟我学spring3(1-7)

    【第六章】 AOP 之 6.8 切面实例化模型 ——跟我学spring3 【第六章】 AOP 之 6.9 代理机制 ——跟我学spring3 【第七章】 对JDBC的支持 之 7.1 概述 ——跟我学spring3 【第七章】 对JDBC的支持 之 7.2 ...

    spring.doc

    4 面向切面编程 52 4.1 代理模式 52 代理模式拓展: 52 4.1.1 JDK动态代理 58 JDK动态代理拓展: 59 4.1.2 CGLIB做代理 66 CGLIB动态代理拓展: 68 4.1.3 Spring的动态代理 71 4.2 AOP编程 71 4.2.1概念: 71 Spring...

    Spring 2.0 开发参考手册

    6. 使用Spring进行面向切面编程(AOP) 6.1. 简介 6.1.1. AOP概念 6.1.2. Spring AOP的功能和目标 6.1.3. Spring的AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个...

    Spring API

    6. 使用Spring进行面向切面编程(AOP) 6.1. 简介 6.1.1. AOP概念 6.1.2. Spring AOP的功能和目标 6.1.3. AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点...

    spring发展史与优势

    Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 SpringMVC 和持久层 Spring JDBC ...

    Spring面试题含答案.pdf

    53. 在 Spring AOP 中,关注点和横切关注的区别是什么? 54. 连接点 55. 通知 56. 切点 57. 什么是引入? 58. 什么是目标对象? 59. 什么是代理? 60. 有几种不同类型的自动代理? 61. 什么是织入。什么是织入应用...

Global site tag (gtag.js) - Google Analytics