【Spring框架】AOP切面编程的理解与实现

    科技2026-02-15  16

    AOP的概念

    AOP(Aspect Oriented Programming),即面向切面编程,利用一种称为"横切"的技术,剖开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

    AOP开发术语

    连接点(Joinpoint):连接点是程序类中客观存在的方法,可被Spring拦截并切入内容。切入点(Pointcut):被Spring切入连接点。通知、增强(Advice):可以为切入点添加额外功能,分为:前置通知、后置通知、异常通知、环绕通知等。目标对象(Target):代理的目标对象引介(Introduction):一种特殊的增强,可在运行期为类动态添加Field和Method。织入(Weaving):把通知应用到具体的类,进而创建新的代理类的过程。代理(Proxy):被AOP织入通知后,产生的结果类。切面(Aspect):由切点和通知组成,将横切逻辑织入切面所指定的连接点中。

    AOP增强类

    前置增强:MethodBeforeAdvice

    后置增强:AfterAdvice

    后置增强:AfterReturningAdvice

    异常增强:ThrowsAdvice

    环绕增强:MethodInterceptor

    切入点表达式

    匹配包名:execution(* com.robot.service.* .*(…))

    返回值任意,com.robot.service包下面的任意类,下面的任意方法,参数任意 <!--匹配参数--> <aop:pointcut id="myPointCut" expression="execution(* *(com.robot.pojo.User))" /> <!--匹配方法名(无参)--> <aop:pointcut id="myPointCut" expression="execution(* save())" /> <!--匹配方法名(任意参数)--> <aop:pointcut id="myPointCut" expression="execution(* save(..))" /> <!--匹配返回值类型--> <aop:pointcut id="myPointCut" expression="execution(com.robot.pojo.User *(..))" /> <!--匹配类名--> <aop:pointcut id="myPointCut" expression="execution(* com.robot.service.userService.impl.UserServiceImpl.*(..))" /> <!--匹配包名--> <aop:pointcut id="myPointCut" expression="execution(* com.robot.service.*.*(..))" /> <!--匹配包名、以及子包名--> <aop:pointcut id="myPointCut" expression="execution(* com.robot..*.*(..))" />

    AOP的实现

    1、环境搭建

    导入依赖

    <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.1.6.RELEASE</version> </dependency>

    在配置文件中引入AOP命名空间

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> </beans>

    2、创建切面类

    以后置增强为例基础AfterReturningAdvice接口,重写afterReturning方法 public class MyAfterAdvice implements AfterReturningAdvice { public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { System.out.println("后置增强:" + method.getName() + " 增强方法:" + o.getClass().getSimpleName()); } }

    3、创建需要被增强的类和接口

    将要实现的效果就是,在调用此方法时,此方法会被增强 public interface UserDao { int insert(); } public class UserDaoImpl implements UserDao { public int insert() { System.out.println("UserDaoImpl::insert..."); return 0; } }

    4、修改配置文件

    配置aop,expression为切入点表达式具体行为execution(* com.robot.service.* .*(…)):返回值任意,com.robot.service包下面的任意类,下面的任意方法,参数任意 <bean name="userService" class="com.robot.service.impl.UserServiceImpl"/> <bean name="myAfterAdvice" class="com.robot.aop.MyAfterAdvice"/> <aop:config> <aop:pointcut id="myPointcut" expression="execution(* com.robot.service.*.*(..))"/> <aop:advisor advice-ref="myAfterAdvice" pointcut-ref="myPointcut"/> </aop:config>

    5、测试

    调用service层中的方法 public class UserServiceTest { @Test public void userServiceTest() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) applicationContext.getBean("userService"); userService.insert(); } }

    结果如下

    UserDaoImpl::insert... 后置增强:insert 增强方法:Integer

    在被调用的insert()方法的后面切入了增强方法,输出了方法内的语句,说明方法增强成功

    总结

    通过AOP提供的编码流程,更便利的定制切面,更方便的定制了动态代理。

    进而彻底解决了辅助功能冗余的问题;

    业务类中职责单一性得到更好保障;

    辅助功能也有很好的复用性。

    Processed: 0.020, SQL: 9