浙江工业大学logo-文字.png

JavaEE实验十
2021/2022(1)
浙江工业大学logo.png

  1. 实验十 Sping 的面向切面编程(AOP

学生姓名 张坤
学生学号 201906061726
学生班级 软件工程1903
任课教师 韩珊珊
提交日期 2021年12月12日

计算机科学与技术学院

一、基础实验——使用@AspectJ 实现AOP

实验内容及步骤

新建项目

导入maven

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-aspects</artifactId>
  5. <version>5.3.8</version>
  6. </dependency>
  7. <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
  8. <dependency>
  9. <groupId>org.springframework</groupId>
  10. <artifactId>spring-core</artifactId>
  11. <version>5.3.8</version>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.springframework</groupId>
  15. <artifactId>spring-context</artifactId>
  16. <version>5.3.8</version>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework</groupId>
  20. <artifactId>spring-beans</artifactId>
  21. <version>5.3.8</version>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.springframework</groupId>
  25. <artifactId>spring-expression</artifactId>
  26. <version>5.3.8</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.springframework</groupId>
  30. <artifactId>spring-aop</artifactId>
  31. <version>5.3.8</version>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.projectlombok</groupId>
  35. <artifactId>lombok</artifactId>
  36. <version>RELEASE</version>
  37. <scope>compile</scope>
  38. </dependency>
  39. </dependencies>

搭建spring框架—切面

基于xml

在spring-prj3 中新建cn.edu.zjut.po 包,并在其中创建持久化类Customer.java,代码片段如下:

  1. @Data
  2. public class Customer {
  3. private int customerId;
  4. private String account;
  5. private String password;
  6. public Customer(int customerId, String account, String password) {
  7. this.customerId = customerId;
  8. this.account = account;
  9. this.password = password;
  10. System.out.println("create Customer");
  11. }
  12. }

在spring-prj3 中新建cn.edu.zjut.dao 包,并在其中创建ICustomerDAO 接口定义数据持久层的操作(代码略),以及实现类CustomerDAO 实现数据持久层的操作,具体代码如下:

  1. public interface ICustomerDAO {
  2. public void save(Customer transientInstance);
  3. public void update(Customer transientInstance);
  4. public void delete(Customer transientInstance);
  5. public void findByHQL(String hql);
  6. }
  1. public class CustomerDAO implements ICustomerDAO{
  2. @Override
  3. public void save(Customer transientInstance) {
  4. System.out.println("execute --save()-- method.");
  5. }
  6. @Override
  7. public void delete(Customer transientInstance) {
  8. System.out.println("execute --delete()-- method.");
  9. }
  10. @Override
  11. public void update(Customer transientInstance) {
  12. System.out.println("execute --update()-- method.");
  13. }
  14. @Override
  15. public void findByHQL(String hql) {
  16. System.out.println("execute --findByHQL()-- method.");
  17. }
  18. }

在spring-prj3 中新建cn.edu.zjut.service 包,并在其中创建IUserService 接口(代码略),以及实现类UserService,代码片段如下:

  1. public interface IUserService {
  2. public void addUser(Customer cust);
  3. public void delUser(Customer cust);
  4. public void updateUser(Customer cust);
  5. public void findUser(Customer cust);
  6. }
  1. public class UserService implements IUserService{
  2. private ICustomerDAO customerDAO = null;
  3. public UserService(ICustomerDAO customerDAO) {
  4. this.customerDAO = customerDAO;
  5. }
  6. public void setCustomerDAO(ICustomerDAO customerDAO) {
  7. System.out.println("call setCustomerDAO in UserService.");
  8. this.customerDAO = customerDAO;
  9. }
  10. @Override
  11. public void addUser(Customer cust) {
  12. System.out.println("execute --addUser()-- method.");
  13. customerDAO.save(cust);
  14. }
  15. @Override
  16. public void delUser(Customer cust) {
  17. System.out.println("execute --delUser()-- method.");
  18. customerDAO.delete(cust);
  19. }
  20. @Override
  21. public void updateUser(Customer cust) {
  22. System.out.println("execute --updateUser()-- method.");
  23. customerDAO.update(cust);
  24. }
  25. @Override
  26. public void findUser(Customer cust) {
  27. System.out.println("execute --findUser()-- method.");
  28. customerDAO.findByHQL("from user where id = "+cust.getCustomerId());
  29. }
  30. }

在spring-prj3 中创建Spring 配置文件applicationContext.xml,并在其中配置CustomerDAO 实例和UserService 实例,代码略;

  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:p="http://www.springframework.org/schema/p"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
  7. <bean id="item1" class="cn.edu.zjut.po.Customer">
  8. <constructor-arg index="0" type="int">
  9. <value>1</value>
  10. </constructor-arg>
  11. <constructor-arg index="1" type="java.lang.String">
  12. <value>张三</value>
  13. </constructor-arg>
  14. <constructor-arg index="2" type="java.lang.String">
  15. <value>123456</value>
  16. </constructor-arg>
  17. </bean>
  18. <bean id="item2" class="cn.edu.zjut.po.Customer">
  19. <constructor-arg index="0" type="int">
  20. <value>2</value>
  21. </constructor-arg>
  22. <constructor-arg index="1" type="java.lang.String">
  23. <value>李四</value>
  24. </constructor-arg>
  25. <constructor-arg index="2" type="java.lang.String">
  26. <value>654321</value>
  27. </constructor-arg>
  28. </bean>
  29. <bean id="customerDao" class="cn.edu.zjut.dao.CustomerDAO">
  30. </bean>
  31. <bean id="userService" class="cn.edu.zjut.service.UserService">
  32. <constructor-arg index="0" type="cn.edu.zjut.dao.ICustomerDAO" ref="customerDao"/>
  33. </bean>
  34. </beans>

查看结果
image.png

基于注解

在spring-prj3 中新建cn.edu.zjut.aspect 包, 并在其中创建SecurityHandler.java,用于实现权限检查,并用基于Annotation 的注解方式定义切面,其中用@Aspect 修饰的类是切面类,用@Pointcut 定义切点,用@Before 定义Before 增强处理,具体代码如下:

  1. @Aspect
  2. public class SecurityHandler {
  3. /** 定义Pointcut,Pointcut 的名称是modify,
  4. * 此方法不能有返回值和参数,该方法只是一个标识*/
  5. @Pointcut("execution(* add*(..)) || execution(* del*(..)) || execution(* update*(..))")
  6. private void modify(){};
  7. /** 定义Advice,标识在那个切入点何处织入此方法*/
  8. @Before("modify()")
  9. private void checkSecurity() {
  10. System.out.println("---checkSecurity()---");
  11. }
  12. }

修改Spring 配置文件applicationContext.xml,在头文件中添加“xmlns:aop”的命名申明,并在“xsischemaLocation”中指定aop 配置的schema 的地址,同时增加对SecurityHandler 实例的配置,并启动注解配置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:p="http://www.springframework.org/schema/p"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  8. http://www.springframework.org/schema/aop
  9. http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
  10. <!-- 启动使用注解配置AOP 支持-->
  11. <aop:aspectj-autoproxy proxy-target-class="true" />
  12. <bean id="securityHandler"
  13. class="cn.edu.zjut.aspect.SecurityHandler" />
  14. ...
  15. </beans>

查看效果
image.png
在spring-prj3 的cn.edu.zjut.aspect 包中创建SecurityHandler2.java,用于实现权限检查,具体代码如下:

  1. public class SecurityHandler2 {
  2. private void checkSecurity() {
  3. System.out.println("---checkSecurity()2---");
  4. }
  5. }

修改Spring 配置文件applicationContext.xml,增加对SecurityHandler2 实例的配置,并使用XML 配置文件的方式定义切面,代码片段如下

  1. <bean id="securityHandler2"
  2. class="cn.edu.zjut.aspect.SecurityHandler2" />
  3. <!-- 配置文件的方式-->
  4. <aop:config>
  5. <aop:aspect id="security" ref="securityHandler2">
  6. <aop:pointcut id="modify"
  7. expression="execution(* *.add*(..))" />
  8. <aop:before method="checkSecurity" pointcut-ref="modify" />
  9. </aop:aspect>
  10. </aop:config>

image.png

实验总结

(1)运行结果截图;
(2)根据实验过程,查找相关资料,整理Spring AOP 中的基本概念(如切面、 增强处理、切点等),并记录下来;
(3)根据实验过程,总结Spring AOP 的基本步骤,以及使用基于Annotation 的 注解方式或基于XML 配置文件的方式来定义切入点和增强处理的基本方 法,并记录下来;
(4)根据实验步骤11 或15,查找AspectJ 切入点表达式的相关资料,记录其中 @Pointcut 注解中切入点表达式的含义;若切入点是cn.edu.zjut.service 包下 所有实现类中的增删改方法,思考切入点表达式应该怎么写,并记录下来;
(5)对比实验步骤10 与13,观察运行后的控制台输出以及相应的程序代码, 总结Spring AOP 优点或作用、适用场景,并记录下来;
(6)碰到的问题及解决方案或思考;
(7)实验收获及总结。