【叨、校长】Spring Aop初探总结
本教程基于Spring官方文档、通俗易懂、老少皆宜!--叨、校长【这个是使用Aspect标准的一个Spring Aop示例】1、业务逻辑类:
package com.master.service;public class UserService implements IUserService {//添加用户public void addUser(String name) {System.out.println("Add user...");System.out.println("=================");}//删除用户public void deleteUser(String name) {System.out.println("Delete user...");System.out.println("=================");}}?2、切面package com.master.aspect;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;/** * 定一个【切面】 * @author Administrator */public class LogAccessAspect {/** * 定义一个切面通知、也就是该【切面】在【连接点】执行的方法--日志输出 * @param ponit 目标连接点对象--也就是【连接点】所在的对象 */public void outPutLog(JoinPoint point){//对象名称String methodName=point.getSignature().getName();System.out.println("【操作日志】-"+methodName);}/** * 定义一个切面通知、也就是该【切面】在【连接点】执行的方法--权限控制 * @param ProceedingJoinPoint ppoint * @return * @throws Throwable */public Object accessControl(ProceedingJoinPoint ppoint) throws Throwable{Object object=null;String user=(String) ppoint.getArgs()[0];String methodName=ppoint.getSignature().getName();if(user.equals("校长")&&methodName.equals("deleteUser")){System.out.println("你没有权限执行删除操作");}else{object=ppoint.proceed();}return object;}}?3、在spring容器中配置aop<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <!-- 这是基于schema的AOP配置、很简单--><aop:config><!-- 定义【切面】 --><aop:aspect id="LAAspect" ref="LogAccessAspectBean"><!-- 声明切面的【切入点】 --><!-- 【切入点表达式】详情见【术语定义】 expression="execution(* com.master.service.*.*(..)) --><aop:pointcut id="userService" expression="execution(* com.master.service.*.*(..))" /><!-- 定义【通知】类型:【Before advice、After advice、After return advice、Around advice、After throwing advice】--><aop:around pointcut-ref="userService" method="accessControl"/><aop:after pointcut-ref="userService" method="outPutLog"/></aop:aspect></aop:config><bean id="LogAccessAspectBean" name="code">import org.springframework.context.ApplicationContext;import org.springframework.context.support.FileSystemXmlApplicationContext;import com.master.service.IUserService;public class TestAop {public static void main(String[] args) {ApplicationContext ctx = new FileSystemXmlApplicationContext("src/applicationContext.xml");//获取业务逻辑类对象IUserService service=(IUserService) ctx.getBean("UserServiceBean");service.addUser("校长");service.deleteUser("校长");}}?5、一些知识点的说明AspectJ使用org.aspectj.lang.JoinPoint接口表示目标类连接点对象?1)JoinPoint??java.lang.Object[] getArgs():获取连接点方法运行时的入参列表;??Signature getSignature() :获取连接点的方法签名对象;??java.lang.Object getTarget() :获取连接点所在的目标对象;??java.lang.Object getThis() :获取代理对象本身;?2)ProceedingJoinPoint?? ?ProceedingJoinPoint继承JoinPoint子接口,它新增了两个用于执行连接点方法的方法:??java.lang.Object proceed() throws java.lang.Throwable:通过反射执行目标对象的连接点处的方法;??java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通过反射执行目标对象连接点处的方法,不过使用新的入参替换原来的入参。?环绕通知使用:ProceedingJoinPoint
切入点表达式:expression="execution(* com.master.service.*.*(..))"表示com.master.service包下,返回值为任意类型;方法名任意;参数不作限制的所有方法。
通知(Advice)类型?前置通知(Before advice) :在某连接点(JoinPoint)之前执行的通知,但这个通知不能阻止连接点前的执行。ApplicationContext中在<aop:aspect>里面使用<aop:before>元素进行声明。后通知(After advice) :当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。ApplicationContext中在<aop:aspect>里面使用<aop:after>元素进行声明。返回后通知(After return advice) :在某连接点正常完成后执行的通知,不包括抛出异常的情况。ApplicationContext中在<aop:aspect>里面使用<after-returning>元素进行声明。环绕通知(Around advice) :包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行。ApplicationContext中在<aop:aspect>里面使用<aop:around>元素进行声明。抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行的通知。 ApplicationContext中在<aop:aspect>里面使用<aop:after-throwing>元素进行声明。