Spring框架学习(三):Spring中的AOP

it2026-01-09  9

AOP编程需要导入的架包: 基本的6个架包+以下两个jar包 aopaliance.jar:AOP包 aspectjweaver.jar AspectJ框架提供的规范

一共是以下的包 项目架构

下面以一个小项目来演示基于XML配置的AOP编程

实体类

Student实体 类

package club.johnny.polo; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Student { private int stuNo ; private String stuName ; private int stuAge ; public int getStuNo() { return stuNo; } public void setStuNo(int stuNo) { this.stuNo = stuNo; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public int getStuAge() { return stuAge; } public void setStuAge(int stuAge) { this.stuAge = stuAge; } @Override public String toString() { return this.stuNo+","+this.stuName+","+this.stuAge; } }

业务类

StudentDao接口

package club.johnny.dao; import club.johnny.polo.Student; public interface StudentDao { void addStudent(Student student); void deleteStudent(int id); }

StudentDao实现类StudentImpl

package club.johnny.dao.impl; import club.johnny.dao.StudentDao; import club.johnny.polo.Student; public class StudentDaoImpl implements StudentDao { public void addStudent(Student student) { // TODO Auto-generated method stub System.out.println(" 模拟增加学生……"); //int a=1/0; } public void deleteStudent(int id) { // TODO Auto-generated method stub System.out.println(" 模拟删除学生……"+id); } }

IStudentService接口

package club.johnny.service; import club.johnny.polo.Student; public interface IStudentService { void addStudent(Student student); void deleteStudent(int id); }

IStudentService实现类StudentServiceImpl

package club.johnny.service.impl; import club.johnny.dao.StudentDao; import club.johnny.polo.Student; import club.johnny.service.IStudentService; public class StudentServiceImpl implements IStudentService { private StudentDao studentDao; public void setStudentDao(StudentDao studentDao) { this.studentDao = studentDao; } public void addStudent(Student student) { // TODO Auto-generated method stub studentDao.addStudent(student); } public void deleteStudent(int id) { // TODO Auto-generated method stub studentDao.deleteStudent(id); } }

通知类

通知类AspectBaseOnXml:模拟log日志通知

package club.johnny.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; public class AspectBaseOnXml { //前置通知 public void logBefore(JoinPoint joinpoint){ System.out.println("前置通知……"); System.out.println("目标类是:"+joinpoint.getTarget()); System.out.println(",被植入增强处理的目标方法是:"+joinpoint.getSignature().getName()); } //后置通知 public void logAfterReturning(JoinPoint joinpoint){ System.out.println("后置通知……"); System.out.println(",被植入增强处理的目标方法是:"+joinpoint.getSignature().getName()); } //环绕通知 public Object logAround(ProceedingJoinPoint proceedingJoinpoin) throws Throwable{ System.out.println("环绕通知实现的[前置通知]……"); //执行被增强方法 该方法会抛出异常 需进行异常捕获 Object obj=proceedingJoinpoin.proceed(); System.out.println("环绕通知实现的[后置通知]……"); return obj; } //异常通知 public void logAfterThrowing(JoinPoint joinpoint,Throwable e){ System.out.println("异常通知:"+e.getMessage()); } //最终通知 public void after() { System.out.println("最终通知……"); } }

配置文件

配置 文件applicatioContext.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- 目标类 --> <bean id="studentDao" class="club.johnny.dao.impl.StudentDaoImpl"> </bean> <bean id="studentService" class="club.johnny.service.impl.StudentServiceImpl"> <property name="studentDao" ref="studentDao"> </property> </bean> <!-- 定义切面 --> <bean id="myaspectBaseOnXml" class="club.johnny.aop.AspectBaseOnXml"> </bean> <!-- aop编程 --> <aop:config> <!-- 配置切面 --> <aop:aspect ref="myaspectBaseOnXml"> <!-- 配置切点 --> <aop:pointcut expression="execution(public * club.johnny.service.impl.StudentServiceImpl.addStudent(..))" id="pointcut"/> <!-- 关联通知和切入点 --> <!-- 前置通知 --> <aop:before method="logBefore" pointcut-ref="pointcut"></aop:before> <!-- 后置通知 在方法返回之后执行 可以获得方法的返回值 returning属性:用于设置后置通知的第二个参数的名称 类型是Object --> <aop:after-returning method="logAfterReturning" pointcut-ref="pointcut" returning="returnVal"></aop:after-returning> <!-- 环绕通知 --> <aop:around method="logAround" pointcut-ref="pointcut"></aop:around> <!-- 最终通知 --> <aop:after method="after" pointcut-ref="pointcut"></aop:after> </aop:aspect> </aop:config> </beans>

配置过程: 首先需要将通知类、业务类纳入Spring的IOC容器中

<bean id="studentDao" class="club.johnny.dao.impl.StudentDaoImpl"> </bean> <bean id="studentService" class="club.johnny.service.impl.StudentServiceImpl"> <property name="studentDao" ref="studentDao"> </property> </bean> <!-- 定义切面 --> <bean id="myaspectBaseOnXml" class="club.johnny.aop.AspectBaseOnXml"> </bean>

然后定义切点

<!-- 配置切点 --> <aop:pointcut expression="execution(public * club.johnny.service.impl.StudentServiceImpl.addStudent(..))" id="pointcut"/>

最后通过pointcut-ref将切点与通知连接起来

<!-- 关联通知和切入点 --> <!-- 前置通知 --> <aop:before method="logBefore" pointcut-ref="pointcut"></aop:before> execution(public * club.johnny.service.impl.StudentServiceImpl.addStudent(..)) *表示任意返回值 “..”表示任意参数列表 若指定类名,需写全类名。

示例:

测试类的测试方法

public static void testAop() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); IStudentService studentService=(IStudentService)context.getBean("studentService"); studentService.addStudent(new Student()); studentService.deleteStudent(2); }

结果

最新回复(0)