http://blog.csdn.net/yerenyuan_pku/article/details/69790950

Spring使用AspectJ进行AOP的开发:注解方式

之前我已讲过Spring使用AspectJ通过配置文件的方式来进行AOP的开发,现在就来讲怎样使用注解方式进行AOP的开发。

  • 创建一个Web项目, 引入相关的jar包。所要导入的jar包如下: 
  • 引入Spring的配置文件。主要引入AOP的约束:

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
    5. http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/aop
    8. http://www.springframework.org/schema/aop/spring-aop.xsd">
    9. </beans>
  • 编写目标类。 
    在Web项目的src目录下创建一个cn.itcast.aop包,并在该包下编写一个Book类:

    1. public class Book {
    2. public void add() {
    3. System.out.println("book add.................");
    4. }
    5. }
  • 编写切面类。 
    再在cn.itcast.aop包下编写一个MyBook增强类:

    1. public class MyBook {
    2. public void before1() {
    3. System.out.println("before........");
    4. }
    5. }
  • 在增强的类上面使用@Aspect注解

    1. @Aspect
    2. public class MyBook {
    3. public void before1() {
    4. System.out.println("before........");
    5. }
    6. }
  • 在增强类的方法里面,使用注解配置通知类型:

    1. @Aspect
    2. public class MyBook {
    3. // 前置通知
    4. // *:方法的访问修饰符,也可写为execution(public void cn.itcast.aop.Book.*(..)),但一般都不会用
    5. @Before("execution(* cn.itcast.aop.Book.*(..))")
    6. public void before1() {
    7. System.out.println("before........");
    8. }
    9. }
    • 1

    AspectJ的AOP的注解:

    • @Aspect:定义切面类的注解
    • @Before:前置通知,相当于BeforeAdvice
    • @AfterReturning:后置通知,相当于AfterReturningAdvice
    • @Around:环绕通知,相当于MethodInterceptor
    • @AfterThrowing:抛出通知,相当于ThrowAdvice
    • @After:最终final通知,不管是否异常,该通知都会执行
    • @Pointcut:定义切入点的注解
  • 开启AspectJ的注解

    1. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  • 创建Book类和MyBook类的两个对象(使用配置文件)

    1. <bean id="book" class="cn.itcast.aop.Book"></bean>
    2. <bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
  • 最后在cn.itcast.aop包下编写一个TestDemo单元测试类

    1. public class TestDemo {
    2. @Test
    3. public void testBook() {
    4. ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    5. Book book = (Book) context.getBean("book");
    6. book.add();
    7. }
    8. }
    • 1

    测试即可。

Spring的JDBC模板

Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架。它针对JavaEE三层中的每一层都提供了不同的解决技术,在dao层,Spring提供了JDBC模板的技术,可对数据库进行CRUD操作。Spring提供了很多持久层技术的模板类简化了编程,如下图: 

我再次加以说明:Spring框架对不同的持久层技术做了封装,如对传统的JDBC使用JdbcTemplate进行了封装,对Hibernate框架使用HibernateTemplate进行了封装。JdbcTemplate对JDBC进行了简单封装,使用类似于dbutils,但是使用并没有dbutils方便,只是提供了一种实现的方式而已。下面来演示使用JdbcTemplate模板类实现CRUD操作。

使用JdbcTemplate模板类实现CRUD操作

首先创建数据库和表,如下:

  1. create database spring_lee;
  2. use spring_lee;
  3. DROP TABLE IF EXISTS `user`;
  4. CREATE TABLE `user` (
  5. `username` varchar(100) DEFAULT NULL,
  6. `password` varchar(100) DEFAULT NULL
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • 1

使用JdbcTemplate模板类还须导入jar包,先引入JdbcTemplate的jar包: 

但我们要知道spring-jdbc-4.2.4.RELEASE.jar包才是最主要的。除此之外还须导入MySQL数据库驱动的jar包。

添加操作

在src目录下创建一个cn.itcast.jdbcTemplate包,并在该包下编写一个JdbcTemplateDemo1单元测试类。现在要编写一个add方法来测试添加操作。

  1. public class JdbcTemplateDemo1 {
  2. // 1.添加操作
  3. @Test
  4. public void add() {
  5. // 1.设置数据库相关信息(JDBC模板依赖连接池获得数据库连接,所以必须先构造连接池)
  6. DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 数据源
  7. dataSource.setDriverClassName("com.mysql.jdbc.Driver");
  8. dataSource.setUrl("jdbc:mysql:///spring_lee");
  9. dataSource.setUsername("root");
  10. dataSource.setPassword("yezi");
  11. // 2.做添加的操作
  12. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  13. String sql = "insert into user values(?,?)";
  14. int rows = jdbcTemplate.update(sql, "liayun", "lee");
  15. System.out.println(rows);
  16. }
  17. }
  • 1

注意:JDBC模板依赖连接池获得数据库连接,所以必须先构造连接池,然后再创建JdbcTemplate模板类对象。而且还须用到JdbcTemplate模板类的update方法: 
 
这个方法中有两个参数:

  • 第一个参数是sql语句。
  • 第二个参数是传递的参数值,Object类型的可变参数。

修改操作

现在要在单元测试类中编写一个update方法来测试修改操作。

  1. public class JdbcTemplateDemo1 {
  2. // 2.修改操作
  3. @Test
  4. public void update() {
  5. // 1.设置数据库相关信息
  6. DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 数据源
  7. dataSource.setDriverClassName("com.mysql.jdbc.Driver");
  8. dataSource.setUrl("jdbc:mysql:///spring_lee");
  9. dataSource.setUsername("root");
  10. dataSource.setPassword("yezi");
  11. // 实现修改操作
  12. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  13. String sql = "update user set password=? where username=?";
  14. int rows = jdbcTemplate.update(sql, "9999", "liayun");
  15. System.out.println(rows);
  16. }
  17. }
  • 1

删除操作

现在要在单元测试类中编写一个delete方法来测试删除操作。

  1. public class JdbcTemplateDemo1 {
  2. // 3.删除操作
  3. @Test
  4. public void delete() {
  5. // 1.设置数据库相关信息
  6. DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 数据源
  7. dataSource.setDriverClassName("com.mysql.jdbc.Driver");
  8. dataSource.setUrl("jdbc:mysql:///spring_lee");
  9. dataSource.setUsername("root");
  10. dataSource.setPassword("yezi");
  11. // 实现删除操作
  12. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  13. String sql = "delete from user where username=?";
  14. int rows = jdbcTemplate.update(sql, "liayun");
  15. System.out.println(rows);
  16. }
  17. }
  • 1

查询操作

查询表中的记录数

现在要在单元测试类中编写一个testCount方法来测试查询表中记录数的操作。

  1. public class JdbcTemplateDemo1 {
  2. // 查询表记录数
  3. @Test
  4. public void testCount() {
  5. // 1.设置数据库相关信息
  6. DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 数据源
  7. dataSource.setDriverClassName("com.mysql.jdbc.Driver");
  8. dataSource.setUrl("jdbc:mysql:///spring_lee");
  9. dataSource.setUsername("root");
  10. dataSource.setPassword("yezi");
  11. // 2.创建JdbcTemplate模板类的对象
  12. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  13. // 3.sql语句
  14. String sql = "select count(*) from user";
  15. // 4.调用JdbcTemplate模板类里面的方法
  16. // 返回int类型
  17. int count = jdbcTemplate.queryForObject(sql, Integer.class);
  18. System.out.println(count);
  19. }
  20. }
  • 1

在查询表中记录数的操作时,用到了JdbcTemplate模板类里面的queryForObject方法,如下: 
 
这个方法中有两个参数:

  • 第一个参数:sql语句
  • 第二个参数:返回类型的class

查询返回对象

使用JdbcTemplate模板类进行查询操作的时候,还是比较麻烦的。前面我也说过JdbcTemplate对JDBC进行了简单封装,使用类似于dbutils,但是使用并没有dbutils方便,只是提供了一种实现的方式而已。我是为何这么说呢?因为在dbutils里面帮我们编写好了一些实现类,使用这些实现类可以封装结果,这些实现类都实现了接口ResultSetHandler;使用JdbcTemplate模板类进行查询操作返回数据结果的时候,虽然在JdbcTemplate模板类中有个接口,但是并没有提供实现类,故还需要自己编写实现类来封装结果。 
好了,接下来复习一下编写JDBC最原始的代码做查询操作,基本功不要忘记了啊! 
首先在cn.itcast.jdbcTemplate包下编写一个User类。

  1. public class User {
  2. private String username;
  3. private String password;
  4. public String getUsername() {
  5. return username;
  6. }
  7. public void setUsername(String username) {
  8. this.username = username;
  9. }
  10. public String getPassword() {
  11. return password;
  12. }
  13. public void setPassword(String password) {
  14. this.password = password;
  15. }
  16. @Override
  17. public String toString() {
  18. return "User [username=" + username + ", password=" + password + "]";
  19. }
  20. }
  • 1

然后再在该包下编写一个JdbcTemplateDemo2单元测试类,编写JDBC最原始的代码做查询操作。

  1. public class JdbcTemplateDemo2 {
  2. // jdbc最原始的代码做查询操作
  3. @Test
  4. public void testJDBC() {
  5. Connection conn = null;
  6. PreparedStatement psmt = null;
  7. ResultSet rs = null;
  8. try {
  9. Class.forName("com.mysql.jdbc.Driver");
  10. conn = DriverManager.getConnection("jdbc:mysql:///spring_lee", "root", "yezi");
  11. String sql = "select * from user where username=?";
  12. // 对sql进行预编译操作
  13. psmt = conn.prepareStatement(sql);
  14. psmt.setString(1, "mary");
  15. // 执行sql
  16. rs = psmt.executeQuery();
  17. // 遍历结果
  18. while (rs.next()) {
  19. String username = rs.getString("username");
  20. String password = rs.getString("password");
  21. User user = new User();
  22. user.setUsername(username);
  23. user.setPassword(password);
  24. System.out.println(user);
  25. }
  26. } catch (Exception e) {
  27. } finally {
  28. try {
  29. rs.close();
  30. psmt.close();
  31. conn.close();
  32. } catch (Exception e2) {
  33. }
  34. }
  35. }
  36. }
  • 1

接下来,就来讲如何使用JdbcTemplate模板类进行查询操作并返回一个User类的对象。其中就要用到JdbcTemplate模板类里面的queryForObject方法: 

这个方法有3个参数:

  • 第一个参数:sql语句
  • 第二个参数:RowMapper接口 
    1. 之前使用dbutils进行查询时,返回结果有ResultSetHandler接口,但是在dbutils里面有其对应的实现类。
    2. 使用JdbcTemplate模板类的时候,虽然提供了RowMapper接口,但是这个接口没有实现类,需要自己进行实现,然后进行数据封装。
  • 第三个参数:可变参数

现在要在JdbcTemplateDemo2单元测试类中编写一个testObject方法来测试查询时返回一个User类对象的操作。

  1. public class JdbcTemplateDemo2 {
  2. // 1.查询返回对象
  3. @Test
  4. public void testObject() {
  5. // 1.设置数据库相关信息
  6. DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 数据源
  7. dataSource.setDriverClassName("com.mysql.jdbc.Driver");
  8. dataSource.setUrl("jdbc:mysql:///spring_lee");
  9. dataSource.setUsername("root");
  10. dataSource.setPassword("yezi");
  11. // 2.创建JdbcTemplate对象
  12. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  13. // 3.sql语句
  14. String sql = "select * from user where username=?";
  15. // 4.调用方法执行
  16. // 第二个参数是接口,RowMapper,要自己创建一个类实现这个接口,在里面进行封装
  17. User user = jdbcTemplate.queryForObject(sql, new MyRowMapper(), "mary");
  18. System.out.println(user);
  19. }
  20. }
  • 1

注意,还要编写RowMapper接口的一个实现类。在以上JdbcTemplateDemo2.java源代码文件中编写RowMapper接口的一个MyRowMapper实现类。

  1. // T:表示要将数据封装到哪个类的对象中
  2. class MyRowMapper implements RowMapper<User> {
  3. // 实现接口里面的方法,在方法中实现数据封装
  4. // 第一个参数:返回的结果集,第二个参数是当前的行数(即第几行)
  5. @Override
  6. public User mapRow(ResultSet rs, int rows) throws SQLException {
  7. // 从结果集得到数据
  8. String username = rs.getString("username");
  9. String password = rs.getString("password");
  10. // 封装到对象里面
  11. User user = new User();
  12. user.setUsername(username);
  13. user.setPassword(password);
  14. return user;
  15. }
  16. }
  • 1

查询返回List集合

现在要在JdbcTemplateDemo2单元测试类中编写一个testList方法来测试查询时返回List集合的操作。

  1. public class JdbcTemplateDemo2 {
  2. // 2.返回List集合
  3. @Test
  4. public void testList() {
  5. // 1.设置数据库相关信息
  6. DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 数据源
  7. dataSource.setDriverClassName("com.mysql.jdbc.Driver");
  8. dataSource.setUrl("jdbc:mysql:///spring_lee");
  9. dataSource.setUsername("root");
  10. dataSource.setPassword("yezi");
  11. // 2.查询操作
  12. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  13. String sql = "select * from user";
  14. List<User> list = jdbcTemplate.query(sql, new MyRowMapper());
  15. System.out.println(list);
  16. }
  17. }

在进行查询并返回List集合的操作时,须用到JdbcTemplate模板类里面的query方法: 

或 

Spring配置连接池

在实际开发中,一般都会用Spring配置C3P0连接池,所以下面我就来重点介绍在Spring中如何配置C3P0连接池。 
首先引入Spring的配置文件,主要是引入约束:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:tx="http://www.springframework.org/schema/tx"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context.xsd
  11. http://www.springframework.org/schema/aop
  12. http://www.springframework.org/schema/aop/spring-aop.xsd
  13. http://www.springframework.org/schema/tx
  14. http://www.springframework.org/schema/tx/spring-tx.xsd">
  15. </beans>

接着导入Spring的基本jar包,除此之外,还要导入C3P0的jar包: 

试想要是以前在Web项目中配置C3P0连接池,势必会写这样的代码:

  1. ComboPooledDataSource dataSource = new ComboPooledDataSource();
  2. dataSource.setDriverClass(driverClass);
  3. dataSource.setJdbcUrl(jdbcUrl);
  4. dataSource.setUser(user);
  5. dataSource.setPassword(password);

而现在我们就可以在Spring配置文件(bean2.xml)中配置C3P0连接池了,即在Spring配置文件中添加如下配置:

  1. <!-- 配置C3P0连接池 -->
  2. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  3. <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  4. <property name="jdbcUrl" value="jdbc:mysql:///spring_lee"></property>
  5. <property name="user" value="root"></property>
  6. <property name="password" value="yezi"></property>
  7. </bean>

现在举例来演示如何在Spring中配置C3P0连接池了。我的思路是这样的:创建一个UserService类和一个UserDao类,然后在UserService类里面调用UserDao类的方法,在UserDao类中使用JdbcTemplate模板类进行数据库CRUD操作,并且用上C3P0连接池。 
先在src目录下创建一个cn.itcast.c3p0包,并在该包下编写一个UserDao类。

  1. public class UserDao {
  2. // 在Dao里面要得到JdbcTemplate对象
  3. private JdbcTemplate jdbcTemplate;
  4. public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
  5. this.jdbcTemplate = jdbcTemplate;
  6. }
  7. // 添加操作,使用JdbcTemplate模板来实现添加
  8. public void add() {
  9. String sql = "insert into user values(?,?)";
  10. jdbcTemplate.update(sql, "李阿昀", "lee");
  11. }
  12. }

再在该包下编写一个UserService类,并在UserService类里面调用UserDao类的add方法。

  1. public class UserService {
  2. private UserDao userDao;
  3. public void setUserDao(UserDao userDao) {
  4. this.userDao = userDao;
  5. }
  6. public void add() {
  7. userDao.add();
  8. }
  9. }

那么Spring核心配置文件就应该像下面这样配置:

  1. <!-- 配置service和dao以及它们的注入 -->
  2. <bean id="userService" class="cn.itcast.c3p0.UserService">
  3. <property name="userDao" ref="userDao"></property>
  4. </bean>
  5. <bean id="userDao" class="cn.itcast.c3p0.UserDao">
  6. <property name="jdbcTemplate" ref="jdbcTemplate"></property>
  7. </bean>
  8. <!-- 配置JdbcTemplate模板类的对象 -->
  9. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  10. <!-- 注入dataSource,因为在其源代码中dataSource属性有其对应的set方法,故可直接注入 -->
  11. <property name="dataSource" ref="dataSource"></property>
  12. </bean>

从上面的配置可看出:UserDao中注入了JdbcTemplate对象,JdbcTemplate对象里面又注入了dataSource。 
最后再在该包下编写一个TestDemo单元测试类。

  1. public class TestDemo {
  2. @Test
  3. public void testBook() {
  4. ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
  5. UserService userService = (UserService) context.getBean("userService");
  6. userService.add();
  7. }
  8. }

(转)Spring使用AspectJ进行AOP的开发:注解方式的更多相关文章

  1. Spring基于AspectJ的AOP的开发——注解

    源码:https://gitee.com/kszsa/dchart 一, AspectJ的概述: AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法所以它有一个专 ...

  2. [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.

    前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...

  3. 在Spring整合aspectj实现aop的两种方式

    -----------------------------基于XML配置方案目标对象接口1 public interface IUserService { public void add(); pub ...

  4. Spring 基于 AspectJ 的 AOP 开发

    Spring 基于 AspectJ 的 AOP 开发 在 Spring 的 aop 代理方式中, AspectJ 才是主流. 1. AspectJ 简介 AspectJ 是一个基于 java 语言的 ...

  5. Spring整合AspectJ的AOP

    学而时习之,不亦说乎!                              --<论语> 看这一篇之前最好先看前面关于AOP的两篇. http://www.cnblogs.com/z ...

  6. Spring声明式事务管理(基于注解方式实现)

    ----------------------siwuxie095                                 Spring 声明式事务管理(基于注解方式实现)         以转 ...

  7. 不依赖Spring使用AspectJ达到AOP面向切面编程

    网上大多数介绍AspectJ的文章都是和Spring容器混用的,但有时我们想自己写框架就需要抛开Spring造轮子,类似使用原生AspectJ达到面向切面编程.步骤很简单,只需要两步. 1.导入依赖 ...

  8. Spring框架的AOP技术(注解方式)

    1. 步骤一:创建JavaWEB项目,引入具体的开发的jar包 * 先引入Spring框架开发的基本开发包 * 再引入Spring框架的AOP的开发包 * spring的传统AOP的开发的包 * sp ...

  9. Spring第七弹—依赖注入之注解方式注入及编码解析@Resource原理

        注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果. 手工装配依赖对象  手工装配依赖对象,在这种方式中又有两种编 ...

随机推荐

  1. 不常见使用的css

    flex和white-space等属性 1.flex属性让所有弹性盒模型对象的子元素都有相同的长度,忽略它们内部的内容.style={{flex:5}},该元素占父元素的六分之五. 2. white- ...

  2. XMU C语言程序设计实践(1)

    题目: 任务1:英雄出世 炎热的夏天午后,小明正在百无聊赖地写c语言程序.忽然,电脑屏幕一阵抖动,浮现下面18×18个看似杂乱无章的数字: 32,  32,  32,  32,  32,  32,  ...

  3. 线程之间的通信socketpair【学习笔记】【原创】

    平台信息:内核:linux3.1.0系统:android5.0平台:tiny4412 作者:庄泽彬(欢迎转载,请注明作者) 说明: 韦老师的安卓视频学习笔记 一.在一个进程中多个线程如何进行通信,主要 ...

  4. Cmake的介绍和使用 Cmake实践【转】

    本文转载自:http://www.cppblog.com/Roger/archive/2011/11/17/160368.html Cmake的介绍和使用 Cmake实践 Cmake优点: 1.    ...

  5. YTU 2975: 我的编号

    2975: 我的编号 时间限制: 1 Sec  内存限制: 128 MB 提交: 42  解决: 15 题目描述 建立一个学生链表,每个链表结点含有学生的基本信息,编号和姓名.现在n个学生站成一列,根 ...

  6. go string []byte相互转换

    string 不能直接和byte数组转换 string可以和byte的切片转换 1,string 转为[]byte var str string = "test" var data ...

  7. ACTION 中 单表查询语句 SQL写法

    JSP页面 <tr> <td class="STYLE1"> <div align="center"> // 单击事件 调用 ...

  8. I.MX6 查找占用UART进程

    /**************************************************************************** * I.MX6 查找占用UART进程 * 说 ...

  9. BZOJ4259:残缺的字符串(FFT与字符串匹配)

    很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想对这两 ...

  10. 使用 dynamic 标记解析JSON字符串(转)

    http://www.cnblogs.com/taotaodetuer/p/4171327.html string jsonStr = "{\"data\": {\&qu ...