AOP(Aspect Oriented Programming),即面向切面编程,利用一种称为"横切"的技术,剖开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
前置增强: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..*.*(..))" />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提供的编码流程,更便利的定制切面,更方便的定制了动态代理。
进而彻底解决了辅助功能冗余的问题;
业务类中职责单一性得到更好保障;
辅助功能也有很好的复用性。
