目录

  • 1 2023广东省精品课程评审申报章节
    • 1.1 申报书
    • 1.2 总结报告
    • 1.3 课程数据信息表
    • 1.4 自评报告
    • 1.5 专家组评语
    • 1.6 相关佐证
  • 2 2020校精品课程评审申报章节
    • 2.1 验收材料总文档
    • 2.2 精品开放课程申报书
    • 2.3 精品开放课程结题验收报告书
    • 2.4 精品开放课程结题验收总结报告
    • 2.5 精品开放课程结题验收项目汇总表
    • 2.6 佐证1.课程基础与建设目标
      • 2.6.1 校本教材
      • 2.6.2 论文
    • 2.7 佐证2.课程设计
      • 2.7.1 课程定位
      • 2.7.2 建设方式
    • 2.8 佐证3.更新与共享
      • 2.8.1 吸引力
      • 2.8.2 内容更新
      • 2.8.3 媒体应用
    • 2.9 佐证4.教学团队
      • 2.9.1 负责人
      • 2.9.2 教学队伍
    • 2.10 佐证5.教学资源
      • 2.10.1 基本资源
        • 2.10.1.1 单元设计
        • 2.10.1.2 课件PPT
        • 2.10.1.3 授课视频
      • 2.10.2 拓展资源
      • 2.10.3 资源创新
    • 2.11 佐证6.课程特色
      • 2.11.1 内容
      • 2.11.2 教学组织
      • 2.11.3 教学模式
    • 2.12 佐证7.目标实现
      • 2.12.1 考评
      • 2.12.2 能学
      • 2.12.3 辅教
  • 3 第一章 Spring 简介
    • 3.1 思政教育
    • 3.2 Sring 概述
    • 3.3 Spring 优点
    • 3.4 Spring 框架结构
    • 3.5 Spring 框架特征
    • 3.6 Spring 入门程序
    • 3.7 Spring 依赖注入
    • 3.8 本章小结
    • 3.9 习题1
  • 4 第二章 Spring中bean的配置和实例化
    • 4.1 思政教育
    • 4.2 Spring中bean的配置
    • 4.3 Bean的实例化
    • 4.4 bean的作用域
    • 4.5 Bean的生命周期
    • 4.6 Bean的装配方式
    • 4.7 应用案例:Annotation注解
    • 4.8 本章小结
    • 4.9 习题2
  • 5 第三章  Spring面向切面编程AOP
    • 5.1 Spring  AOP的基本概念
    • 5.2 通知类型介绍
    • 5.3 JDK动态代理
    • 5.4 Spring AOP
    • 5.5 应用案例:AspectJ开发
    • 5.6 本章小结
    • 5.7 习题3
  • 6 第四章  Mybatis原理
    • 6.1 基本内容
    • 6.2 JDBC的问题
    • 6.3 Hibernate的问题
    • 6.4 MyBatis优势
    • 6.5 MyBatis的工作原理
    • 6.6 MyBatis的数据库准备_MySQL
    • 6.7 应用案例:MyBatis入门程序
    • 6.8 Mybatis数据库基本操作示例
    • 6.9 习题4
  • 7 第五章  Mybatis反向工程
    • 7.1 动态SQL
    • 7.2 应用案例: Mybatis反向(逆向)工程
    • 7.3 Mybatis反向(逆向)工程代码解读
    • 7.4 习题5
  • 8 第六章  Spring、 Mybatis Mapper接口编程
    • 8.1 Mybatis反向工程生成的接口
    • 8.2 应用案例:SpringMVC、 Mybatis  Mapper接口编程
    • 8.3 习题6
  • 9 SpringMVC
    • 9.1 SpringMVC框架
    • 9.2 应用案例:SpringMVC
    • 9.3 应用案例:SpringMVC注解开发
    • 9.4 习题7
  • 10 SpringMVC数据绑定
    • 10.1 SpringMvc的数据绑定流程
    • 10.2 应用案例:SpringMVC参数绑定
    • 10.3 SpringMVC参数绑定数组和集合
    • 10.4 案例SpringMVC参数绑定数组
    • 10.5 习题8
  • 11 第九章、SpringMVC拦截器
    • 11.1 拦截器的实现
    • 11.2 拦截器的配置
    • 11.3 应用案例
    • 11.4 习题9
  • 12 第十章 文件上传
    • 12.1 文件上传原理
    • 12.2 创建工程
    • 12.3 应用案例
    • 12.4 习题10
  • 13 第十一章、课程资源管理系统
    • 13.1 系统需求
    • 13.2 开发环境
    • 13.3 数据库设计
    • 13.4 项目程序设计
  • 14 第十二章 职场沟通技能
    • 14.1 职场沟通原则与理念
  • 15 第十三章 如何与上司、同事沟通
    • 15.1 如何与上司、同事沟通
  • 16 第十四章 软件开发团队建设
    • 16.1 企业级应用开发团队组织技巧培训
应用案例:AspectJ开发

3.5 应用案例:AspectJ开发

AspectJ(也就是AOP)的动机是发现那些使用传统的编程方法无法很好处理的问题。考虑一个要在某些应用中实施安全策略的问题。安全性是贯穿于系统所有模块间的问题,每个模块都需要应用安全机制才能保证整个系统的安全性,很明显这里的安全策略的实施问题就是一个横切关注点,使用传统的编程解决此问题非常的困难而且容易产生差错,这就正是AOP发挥作用的时候了。@AspectJ 使用了Java5 的注解,可以将切面声明为普通的Java类。 在 spring2.0以后,spring新增了对AspectJ 切点表达式的支持;Aspect1.5新增注解功能,通过 JDK5的注解技术,能直接在类中定义切面;新版本的 spring 框架,也都建议使用 AspectJ 来实现 AOP。所以说在 spring AOP 的核心包 Spring-aop-3.2.jar 里面也有对 AspectJ 的支持。

传统的面向对象编程中,每个单元就是一个类,而类似于安全性这方面的问题,它们通常不能集中在一个类中处理因为它们横跨多个类,这就导致了代码无法重用,可维护性差而且产生了大量代码冗余,这是我们不愿意看到的。

面向切面编程的出现正好给处于黑暗中的我们带来了光明,它针对于这些横切关注点进行处理,就好像面向对象编程处理一般的关注点一样。而作为AOP的具体实现之一的AspectJ,它向Java中加入了连接点(Join Point)这个新概念,其实它也只是现存的一个Java概念的名称而已。它向Java语言中加入少许新结构:切点(pointcut)、通知(Advice)、类型间声明(Inter-type declaration)和方面(Aspect)。切点和通知动态地影响程序流程,类型间声明则是静态的影响程序的类等级结构,而方面则是对所有这些新结构的封装。

一个连接点是程序流中指定的一点。切点收集特定的连接点集合和在这些点中的值。一个通知是当一个连接点到达时执行的代码,这些都是AspectJ的动态部分。其实连接点就好比是程序中的一条一条的语句,而切点就是特定一条语句处设置的一个断点,它收集了断点处程序栈的信息,而通知就是在这个断点前后想要加入的程序代码。AspectJ中也有许多不同种类的类型间声明,这就允许程序员修改程序的静态结构、名称、类的成员以及类之间的关系。AspectJ中的方面是横切关注点的模块单元。它们的行为与Java语言中的类很像,但是方面还封装了切点、通知以及类型间声明。

Aspect 通知类型,定义了类型名称以及方法格式。类型如下:

before:前置通知(应用:各种校验),在方法执行前执行,如果通知抛出异常,阻止方法运行

afterReturning:后置通知(应用:常规数据处理),方法正常返回后执行,如果方法中抛出异常,通知无法执行,必须在方法执行后才执行,所以可以获得方法的返回值。

around:环绕通知(应用:十分强大,可以做任何事情),方法执行前后分别执行,可以阻止方法的执行,必须手动执行目标方法。

afterThrowing:抛出异常通知(应用:包装异常信息),方法抛出异常后执行,如果方法没有抛出异常,无法执行。

after:最终通知(应用:清理现场),方法执行完毕后执行,无论方法中是否出现异常。

这里最重要的是around,环绕通知,它可以代替上面的任意通知。

以下是一个使用AspectJ框架进行开发的案例:

案例:AspectJ框架开发

本案例我们采用注解方式开发,程序结构如下:

其中UserDao.java代码如下:

package dao;

public interface UserDao {

public void addUser();

public void delUser();

}

UserDaoImpl.java类实现了UserDao接口,并对该类用@Repository("userDao")进行注解,其代码如下:

package impl;

import dao.UserDao;

@Repository("userDao")

public class UserDaoImpl implements UserDao {

@Override

public void addUser() {

         //int i=1/0;

System.out.println("添加用户!");

}

@Override

public void delUser() {

System.out.println("删除用户!");

}

}

MyAspect.java类是要增强的新功能,这些功能希望添加到原来的旧类里面,从而使用旧类里面的方法拥有更加强大的功能,在这个类里我们设计了多种增强方法并对这些方法进行了注解,我们使用了以下aop注解:

@Aspect 声明切面,修饰切面类,从而获得 通知。

@Before前置

@AfterReturning后置

@Around环绕

@AfterThrowing抛出异常

@After最终

@PointCut 切入点,修饰方法 private  void xxx(){}  之后通过“方法名”获得切入点引用

MyAspect.java文件代码如下:

package aspect;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.AfterReturning;

import org.aspectj.lang.annotation.AfterThrowing;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;

import org.springframework.stereotype.Component;

/** 切面类 */

@Aspect

@Component

public class MyAspect {

//定义切入点所扫描的类,以发现这些类中要增强的方法。这里我们扫描包impl中的所有类

@Pointcut("execution(* impl.*.*(..))")

// 使用一个无参无返回值的方法定义切入点,该方法代表要增强的类中的方法

private void myPointCut(){}

//定义前置通知,该通知位于调用代码之前

@Before("myPointCut()")

public void myBefore(JoinPoint joinPoint) {

System.out.print("检查权限!");

}

//后置通知

@AfterReturning(value="myPointCut()")

public void myAfterReturning(JoinPoint joinPoint) {

System.out.print("添加操作记录到数据库!" );

}

//环绕通知

@Around("myPointCut()")

public Object myAround(ProceedingJoinPoint proceedingJoinPoint)

            throws Throwable {

System.out.println("环绕通知:检查权限!");

//调用被增强的目标类的方法

Object obj = proceedingJoinPoint.proceed();

System.out.println("环绕通知:添加操作记录到数据库!");

return obj;

}

//异常通知

@AfterThrowing(value="myPointCut()",throwing="e")

public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {

System.out.println("异常通知,表示程序出错了!" + e.getMessage());

}

//最终通知

@After("myPointCut()")

public void myAfter() {

System.out.println("这里的操作可以是关闭连接、关闭文件等收尾工作");

}

}

由于使用了注解,我们编辑配置文件如下:

<?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-4.3.xsd

  http://www.springframework.org/schema/aop

  http://www.springframework.org/schema/aop/spring-aop-4.3.xsd

  http://www.springframework.org/schema/context

  http://www.springframework.org/schema/context/spring-context-4.3.xsd">

      <!-- 指定需要扫描的包,使注解生效 -->

      <context:component-scan base-package="aspect" />

      <context:component-scan base-package="impl" />

      <!-- 启动基于注解的声明式AspectJ支持 -->

      <aop:aspectj-autoproxy />

</beans>

由于存在注解代码的类位于不同的包中,我们使用了两行代码来指定要扫描这两个包中的类。

<context:component-scan base-package="aspect" />

<context:component-scan base-package="impl" /> 

测试类代码如下:

import org.springframework.context.ApplicationContext;

import  org.springframework.context.support.ClassPathXmlApplicationContext;

import dao.UserDao;

public class TestAnnotationAspectj {

public static void main(String args[]) {

String xmlPath ="applicationContext.xml";

ApplicationContext applicationContext =

                 new ClassPathXmlApplicationContext(xmlPath);

UserDao userDao = (UserDao) applicationContext.getBean("userDao");

userDao.addUser();

}

}

程序运行结果如下

环绕通知:检查权限!

检查权限!

添加用户

环绕通知:添加操作记录到数据库!

这里的操作可以是关闭连接、关闭文件等收尾工作

添加操作记录到数据库!

如果我们把UserDaoImpl.java类中的代码int i=1/0;的注释去掉,则会触发异常通知,读者可以自行尝试。