aop: Aspect Oriented Programing 面向切面编程
就是将与业务无关但为业务模块所共同调用的逻辑或责任封装起来,用于减少系统的重复代码,降低模块之间的耦合度,有利于未来的可操作性和可维护性。
其核心思想就是:将应用程序中的商业逻辑同对其提供支持的通用服务进行分离;
如:将日志记录,性能统计,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过将这些行为的分离,我们可以将它们独立到非指导业务逻辑的方法中,进而该百年这些行为的时候不影响业务逻辑的代码。
特征:
①aop面向切面编程,能够实现不修改代码来完成功能扩展;
②aop采用横向抽取机制,取代传统的纵向继承体系重复性代码;
③aop底层使用动态代理的方式实现。
优点:
减少代码重复量;
降低业务之间的耦合度;
提高代码维护性。
需要的包:
-
- <dependency>
- <groupId>org.aspectjgroupId>
- <artifactId>aspectjweaverartifactId>
- <version>1.9.8version>
- dependency>
-
通知(Advice/增强):
- public class MyAdvice {
-
- public void before(){
- System.out.println("before:前置通知");
- }
-
- public void afterReturn(){
- System.out.println("afterReturn:后置通知");
- }
-
- public void around(ProceedingJoinPoint joinPoint) throws Throwable {
- System.out.println("around:环绕通知+");
- joinPoint.proceed();
- System.out.println("around:环绕通知-");
- }
-
- public void after(){
- System.out.println("after:最终通知");
- }
-
- public void afterThrowing(Exception ex){
- System.out.println("afterThrowing:异常通知");
- System.out.println("异常:"+ex.getMessage());
- }
- }
- <context:component-scan base-package="com.service"/>
- <bean id="myAdvise" class="com.advise.MyAdvice"/>
-
- <aop:config>
-
- <aop:pointcut id="pc" expression="execution(* com.service.IUserService.insert(..))"/>
-
- <aop:aspect ref="myAdvise">
-
- <aop:before method="before" pointcut-ref="pc"/>
- <aop:after-returning method="afterReturn" pointcut-ref="pc"/>
- <aop:after method="after" pointcut-ref="pc"/>
- <aop:around method="around" pointcut-ref="pc"/>
- <aop:after-throwing throwing="ex" method="afterThrowing" pointcut-ref="pc"/>
- aop:aspect>
- aop:config>
- //测试类
- ApplicationContext ac = new ClassPathXmlApplicationContext("spring-1.xml");
- IUserService userService = ac.getBean(IUserService.class);
- userService.select();
- userService.insert(new User());
效果:

异常通知会在发生异常之后执行。
xml配置:
-
- <context:component-scan base-package="com.advise,com.service"/>
-
- <aop:aspectj-autoproxy/>
增强类配置:
- @Component
- @Aspect
- public class MyAdvice {
-
- /**
- * 配置公共切入点
- * 第一个 * 匹配方法返回类型
- * 第二个 * 匹配方法名
- * .. 匹配方法参数
- */
- @Pointcut("execution(* com.service.IUserService.*(..))")
- public void pc(){
- }
-
- @Before("pc()")
- public void before(){
- System.out.println("before:前置通知");
- }
-
- @AfterReturning("pc()")
- public void afterReturn(){
- System.out.println("afterReturn:后置通知");
- }
-
- @Around("pc()")
- public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
- System.out.println("around:环绕通知+");
- joinPoint.proceed();
- System.out.println("around:环绕通知-");
- return null;
- }
-
- @After("pc()")
- public void after(){
- System.out.println("after:最终通知");
- }
-
- @AfterThrowing(pointcut = "pc()",throwing = "ex")
- public void afterThrowing(Exception ex){
- System.out.println("afterThrowing:异常通知");
- System.out.println("异常:"+ex.getMessage());
- }
- }
测试效果:
