JavaEE实验十
2021/2022(1)
实验十 Sping 的面向切面编程(AOP)
学生姓名 张坤
学生学号 201906061726
学生班级 软件工程1903
任课教师 韩珊珊
提交日期 2021年12月12日
计算机科学与技术学院
一、基础实验——使用@AspectJ 实现AOP
实验内容及步骤
新建项目
导入maven
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.3.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.8</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
搭建spring框架—切面
基于xml
在spring-prj3 中新建cn.edu.zjut.po 包,并在其中创建持久化类Customer.java,代码片段如下:
@Data
public class Customer {
private int customerId;
private String account;
private String password;
public Customer(int customerId, String account, String password) {
this.customerId = customerId;
this.account = account;
this.password = password;
System.out.println("create Customer");
}
}
在spring-prj3 中新建cn.edu.zjut.dao 包,并在其中创建ICustomerDAO 接口定义数据持久层的操作(代码略),以及实现类CustomerDAO 实现数据持久层的操作,具体代码如下:
public interface ICustomerDAO {
public void save(Customer transientInstance);
public void update(Customer transientInstance);
public void delete(Customer transientInstance);
public void findByHQL(String hql);
}
public class CustomerDAO implements ICustomerDAO{
@Override
public void save(Customer transientInstance) {
System.out.println("execute --save()-- method.");
}
@Override
public void delete(Customer transientInstance) {
System.out.println("execute --delete()-- method.");
}
@Override
public void update(Customer transientInstance) {
System.out.println("execute --update()-- method.");
}
@Override
public void findByHQL(String hql) {
System.out.println("execute --findByHQL()-- method.");
}
}
在spring-prj3 中新建cn.edu.zjut.service 包,并在其中创建IUserService 接口(代码略),以及实现类UserService,代码片段如下:
public interface IUserService {
public void addUser(Customer cust);
public void delUser(Customer cust);
public void updateUser(Customer cust);
public void findUser(Customer cust);
}
public class UserService implements IUserService{
private ICustomerDAO customerDAO = null;
public UserService(ICustomerDAO customerDAO) {
this.customerDAO = customerDAO;
}
public void setCustomerDAO(ICustomerDAO customerDAO) {
System.out.println("call setCustomerDAO in UserService.");
this.customerDAO = customerDAO;
}
@Override
public void addUser(Customer cust) {
System.out.println("execute --addUser()-- method.");
customerDAO.save(cust);
}
@Override
public void delUser(Customer cust) {
System.out.println("execute --delUser()-- method.");
customerDAO.delete(cust);
}
@Override
public void updateUser(Customer cust) {
System.out.println("execute --updateUser()-- method.");
customerDAO.update(cust);
}
@Override
public void findUser(Customer cust) {
System.out.println("execute --findUser()-- method.");
customerDAO.findByHQL("from user where id = "+cust.getCustomerId());
}
}
在spring-prj3 中创建Spring 配置文件applicationContext.xml,并在其中配置CustomerDAO 实例和UserService 实例,代码略;
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="item1" class="cn.edu.zjut.po.Customer">
<constructor-arg index="0" type="int">
<value>1</value>
</constructor-arg>
<constructor-arg index="1" type="java.lang.String">
<value>张三</value>
</constructor-arg>
<constructor-arg index="2" type="java.lang.String">
<value>123456</value>
</constructor-arg>
</bean>
<bean id="item2" class="cn.edu.zjut.po.Customer">
<constructor-arg index="0" type="int">
<value>2</value>
</constructor-arg>
<constructor-arg index="1" type="java.lang.String">
<value>李四</value>
</constructor-arg>
<constructor-arg index="2" type="java.lang.String">
<value>654321</value>
</constructor-arg>
</bean>
<bean id="customerDao" class="cn.edu.zjut.dao.CustomerDAO">
</bean>
<bean id="userService" class="cn.edu.zjut.service.UserService">
<constructor-arg index="0" type="cn.edu.zjut.dao.ICustomerDAO" ref="customerDao"/>
</bean>
</beans>
基于注解
在spring-prj3 中新建cn.edu.zjut.aspect 包, 并在其中创建SecurityHandler.java,用于实现权限检查,并用基于Annotation 的注解方式定义切面,其中用@Aspect 修饰的类是切面类,用@Pointcut 定义切点,用@Before 定义Before 增强处理,具体代码如下:
@Aspect
public class SecurityHandler {
/** 定义Pointcut,Pointcut 的名称是modify,
* 此方法不能有返回值和参数,该方法只是一个标识*/
@Pointcut("execution(* add*(..)) || execution(* del*(..)) || execution(* update*(..))")
private void modify(){};
/** 定义Advice,标识在那个切入点何处织入此方法*/
@Before("modify()")
private void checkSecurity() {
System.out.println("---checkSecurity()---");
}
}
修改Spring 配置文件applicationContext.xml,在头文件中添加“xmlns:aop”的命名申明,并在“xsischemaLocation”中指定aop 配置的schema 的地址,同时增加对SecurityHandler 实例的配置,并启动注解配置AOP 支持,具体代码如下:
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 启动使用注解配置AOP 支持-->
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="securityHandler"
class="cn.edu.zjut.aspect.SecurityHandler" />
...
</beans>
查看效果
在spring-prj3 的cn.edu.zjut.aspect 包中创建SecurityHandler2.java,用于实现权限检查,具体代码如下:
public class SecurityHandler2 {
private void checkSecurity() {
System.out.println("---checkSecurity()2---");
}
}
修改Spring 配置文件applicationContext.xml,增加对SecurityHandler2 实例的配置,并使用XML 配置文件的方式定义切面,代码片段如下
<bean id="securityHandler2"
class="cn.edu.zjut.aspect.SecurityHandler2" />
<!-- 配置文件的方式-->
<aop:config>
<aop:aspect id="security" ref="securityHandler2">
<aop:pointcut id="modify"
expression="execution(* *.add*(..))" />
<aop:before method="checkSecurity" pointcut-ref="modify" />
</aop:aspect>
</aop:config>
实验总结
(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)实验收获及总结。