spring 的aop :面向切面编程。有什么特点呢?和面对对象有什么不同呢?顾名思义,切面编程就是在一个切面上编程,这样解释有点笨。就那日志管理来看,用户登入前,登出后进行日志的记录。那么登入前和登入后便是切面了。
为什么要用aop呢?
1.如果你在用户每个逻辑都写上代码,会显得很冗余。通过aop切面编程将事务放在一个地方,这样便于管理和维护。
2.使业务代码跟干净,便于管理和维护。
之前听大牛说aop是一把双刃剑,但对于初学的我来说,貌似没有被割伤。
aop术语
下图是在网上的图,做的很好:
切面(Aspect): 横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象
通知(Advice): 切面必须要完成的工作
目标(Target): 被通知的对象
代理(Proxy): 向目标对象应用通知之后创建的对象
连接点(Joinpoint):程序执行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。
切点(pointcut):每个类都拥有多个连接点,即连接点是程序类中客观存在的事务。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。
使用spring4 aop
第一步:导包,可以参考:spring4 项目搭建
还需要添加AspectJ(Java中最流行的aop框架):
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.2.2.RELEASE</version> </dependency>
第二步:配置bean文件
配置aop可以通过注解,也可以通过配置文件,项目中建议有配置文件,这样便于修改。我先讲解注解方法
配置自动扫描和AspectJ框架
<!-- 配置自动扫描的aop包 --> <context:component-scan base-package="com.spring.aop"/> <!-- 配置 AspectJ --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
如果aop显示不出来就先xml头文件中导入(我相信大家会导入的,就不多说了)
xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
第三步:业务代码,模拟用户的操作
业务代码AopService
package com.spring.aop; import org.springframework.stereotype.Service; @Service public class AopService { // 用户登入 public void login(){ System.out.println("登入成功"); } // 用户退出 public void loginOut(){ System.out.println("用户退出系统"); } // 用户操作 public void writeABlog(){ System.out.println("用户编写博客"); } // 用户操作 public void deleteABlog(){ System.out.println("用户删除博客"); } }
切面代码:
package com.spring.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Component @Aspect public class LogAspect { @After("execution(public void com.spring.aop.AopService.*(..))") public void afterMethod(JoinPoint joinPoint) { String opreate = joinPoint.getSignature().getName(); System.out.println("ITDragon opreate " + opreate); } }
测试类:
package com.spring.aop; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AopTest { private ApplicationContext ctx = null; { ctx = new ClassPathXmlApplicationContext("beans.xml"); } @Test public void aopTest(){ AopService aopService = (AopService) ctx.getBean("aopService"); aopService.login(); aopService.writeABlog(); aopService.deleteABlog(); aopService.loginOut(); } }
测试结果:
登入成功 ITDragon opreate login 用户编写博客 ITDragon opreate writeABlog 用户删除博客 ITDragon opreate deleteABlog 用户退出系统 ITDragon opreate loginOut
@Before: 前置通知, 在方法执行之前执行
@After: 后置通知, 在方法执行之后执行
@AfterRunning: 返回通知, 在方法返回结果之后执行,方法必须有返回值。需要添加returning = "result",其中result就是返回结构,
@AfterReturning(pointcut="execution(public void com.spring.aop.AopService.*(..))",returning="result")
@AfterThrowing: 异常通知, 在方法抛出异常之后,有异常的时候才执行
@AfterThrowing(pointcut="execution(public void com.spring.aop.AopService.*(..))",throwing="e")
@Around: 环绕通知, 围绕着方法执行
@Component:标识该类受spring管理
@Aspect: 标识该类是一个切面
execution(public void com.spring.aop.AopService.*(..)) : 切入点签名表达式,用*号表示所有,也可以指定,括号内两点表示多个变量,也可以指定,还可以用 && , || , !;以每个execution为一个单位
JoinPoint:连接点,该参数可以访问到更多的数据,还有很多方法可以自己试试。
@Order(n): 切面执行的优先级,n值越小,越优先执行
还有重用切面,等知识我就不过多描述了,毕竟是入门,讲一些常用的就可以了。
使用xml配置文件
package com.spring.aop; import org.aspectj.lang.JoinPoint; public class LogAspect { public String afterMethod(JoinPoint joinPoint) { String opreate = joinPoint.getSignature().getName(); System.out.println("ITDragon opreate " + opreate); return ""; } }
配置文件:
<!-- 扫描切面类 --> <bean class="com.spring.aop.LogAspect" id="logAspect"></bean> <!-- aop配置 --> <aop:config> <!-- 切点 --> <aop:pointcut expression="execution(public void com.spring.aop.AopService.*(..))" id="aop"/> <!-- 切面 : ref 的值是 切面类的id--> <aop:aspect id="aspect" ref="logAspect"> <!-- 前置方法 : pointcut-ref 的值是 切点的id --> <aop:before method="afterMethod" pointcut-ref="aop"/> </aop:aspect> </aop:config>
还是一样的测试方法,其结果为:
ITDragon opreate login 登入成功 ITDragon opreate writeABlog 用户编写博客 ITDragon opreate deleteABlog 用户删除博客 ITDragon opreate loginOut 用户退出系统
感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程