安徽龙山建设有限公司网站,合肥行业网站建设,aso应用优化,工业设计考研学校排名1.前置通知 在目标方法执行之前执行执行的通知。 前置通知方法#xff0c;可以没有参数#xff0c;也可以额外接收一个JoinPoint#xff0c;Spring会自动将该对象传入#xff0c;代表当前的连接点#xff0c;通过该对象可以获取目标对象 和 目标方法相关的信息。 注意可以没有参数也可以额外接收一个JoinPointSpring会自动将该对象传入代表当前的连接点通过该对象可以获取目标对象 和 目标方法相关的信息。 注意如果接收JoinPoint必须保证其为方法的第一个参数否则报错。 配置方式 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beans xmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.2.xsdcontext:annotation-config/context:annotation-configcontext:component-scan base-packagecn.tedu.service,cn.tedu.aop/context:component-scanaop:config proxy-target-classtrue!-- 配置切入点 --aop:pointcut expressionexecution(* cn.tedu.service.UserServiceImpl.addUser(..)) idpc01/!-- 配置切面 --aop:aspect reffirstAspect !-- 前置通知 --aop:before methodbefore pointcut-refpc01//aop:aspect/aop:config
/beans package cn.tedu.service;import org.springframework.stereotype.Service;
/*** UserServiceImple:目标对象*/
Service(userService)
public class UserServiceImple implements UserService {Overridepublic void addUser(String name) {System.out.println(增加用户。。);}Overridepublic void updateUser() {System.out.println(修改用户。。);}Overridepublic void deleteUser() {System.out.println(删除用户。。);}Overridepublic void query() {System.out.println(查询用户。。);}
} package cn.tedu.aop;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.springframework.stereotype.Component;
/*** FirstAspect:切面代码*/
Component
public class FirstAspect {public void before(JoinPoint jp){ // 可以选择额外的传入一个JoinPoint连接点对象必须用方法的第一个参数接收。Class clz jp.getTarget().getClass();Signature signature jp.getSignature(); // 通过JoinPoint对象获取更多信息String name signature.getName();System.out.println(1 -- before...[clz]...[name]...);}
} package cn.tedu.test;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.tedu.service.UserService;
/*** AOPTest测试代码*/
public class AOPTest {Testpublic void test01(){ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml);UserService userService (UserService) context.getBean(userService);userService.addUser(cjj); // 一个连接点}
} 执行结果 1 -- before...[class cn.tedu.service.UserServiceImple]...[addUser]...
增加用户。。 2.环绕通知 在目标方法执行之前和之后都可以执行额外代码的通知。 在环绕通知中必须显式的调用目标方法目标方法才会执行这个显式调用时通过ProceedingJoinPoint来实现的可以在环绕通知中接收一个此类型的形参spring容器会自动将该对象传入注意这个参数必须处在环绕通知的第一个形参位置。 **要注意只有环绕通知可以接收ProceedingJoinPoint而其他通知只能接收JoinPoint。 环绕通知需要返回返回值否则真正调用者将拿不到返回值只能得到一个null。 环绕通知有控制目标方法是否执行、有控制是否返回值、有改变返回值的能力。 环绕通知虽然有这样的能力但一定要慎用不是技术上不可行而是要小心不要破坏了软件分层的“高内聚 低耦合”的目标。 配置方式 !-- 环绕通知 --aop:around methodaround pointcut-refpc1/ public Object around(ProceedingJoinPoint jp) throws Throwable{System.out.println(1 -- around before...);Object obj jp.proceed(); //--显式的调用目标方法System.out.println(1 -- around after...);return obj;} 运行结果 1 -- around before...
增加用户。。
1 -- around after... 3.后置通知 在目标方法执行之后执行的通知。 在后置通知中也可以选择性的接收一个JoinPoint来获取连接点的额外信息但是这个参数必须处在参数列表的第一个。 配置方式 !-- 后置通知 --
aop:after-returning methodafterReturn pointcut-refpc1/ public void afterReturn(JoinPoint jp){Class clz jp.getTarget().getClass();Signature signature jp.getSignature(); String name signature.getName();System.out.println(1 -- afterReturn...[clz]...[name]...);} 执行结果 1 -- before...[class cn.tedu.service.UserServiceImple]...[addUser]...
1 -- around before...
增加用户。。
1 -- around after...
1 -- afterReturn...[class cn.tedu.service.UserServiceImple]...[addUser]... 在后置通知中还可以通过配置获取返回值 一定要保证JoinPoint处在参数列表的第一位否则抛异常 配置方式 !-- 后置通知 --
aop:after-returning methodafterReturn pointcut-refpc1 returningmsg/ public void afterReturn(JoinPoint jp, Object msg){Class clz jp.getTarget().getClass();Signature signature jp.getSignature(); String name signature.getName();System.out.println(1 -- afterReturn...[clz]...[name]...[msg]...);} 执行结果 1 -- before...[class cn.tedu.service.UserServiceImple]...[addUser]...
1 -- around before...
增加用户。。
1 -- around after...
1 -- afterReturn...[class cn.tedu.service.UserServiceImple]...[addUser]...[cjj]... 4.异常通知 在目标方法抛出异常时执行的通知 可以配置传入JoinPoint获取目标对象和目标方法相关信息但必须处在参数列表第一位 另外还可以配置参数让异常通知可以接收到目标方法抛出的异常对象。 配置方法 !-- 异常通知 --
aop:after-throwing methodafterThrow pointcut-refpc1 throwinge/ public void afterThrow(JoinPoint jp,Throwable e){Class clz jp.getTarget().getClass();String name jp.getSignature().getName();System.out.println(1afterThrow..[clz]..[name]..e.getMessage());} 代码报异常后 执行结果 1 -- before...[class cn.tedu.service.UserServiceImple]...[addUser]...
1 -- around before...
1 -- afterThrow..[class cn.tedu.service.UserServiceImple]..[addUser]../ by zero 5.最终通知 是在目标方法执行之后执行的通知。 和后置通知不同之处在于后置通知是在方法正常返回后执行的通知如果方法没有正常返-例如抛出异常则后置通知不会执行。 而最终通知无论如何都会在目标方法调用过后执行即使目标方法没有正常的执行完成。 另外后置通知可以通过配置得到返回值而最终通知无法得到。 最终通知也可以额外接收一个JoinPoint参数来获取目标对象和目标方法相关信息但一定要保证必须是第一个参数。 配置方式 !-- 最终通知 --
aop:after methodafter pointcut-refpc1 / public void after(JoinPoint jp){Class clz jp.getTarget().getClass();String name jp.getSignature().getName();System.out.println(1 -- after..[clz]..[name]...);} 执行结果 1 -- before...[class cn.tedu.service.UserServiceImple]...[addUser]...
1 -- around before...
增加用户。。
1 -- around after...
1 -- afterReturn...[class cn.tedu.service.UserServiceImple]...[addUser]...[cjj]...
1 -- after..[class cn.tedu.service.UserServiceImple]..[addUser]...
cjj 源码 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beans xmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd context:annotation-config/context:annotation-configcontext:component-scan base-packagecn.tedu.service,cn.tedu.aop/context:component-scan!-- proxy-target-class属性值决定是基于接口的还是基于类的代理被创建 --aop:config proxy-target-classtrue !-- 配置切入点 --aop:pointcut expressionexecution(* cn.tedu.service.UserServiceImple.addUser(..)) idpc1/ !-- 配置切入面 --aop:aspect reffirstAspect!-- 前置通知 -- aop:before methodbefore pointcut-refpc1/!-- 环绕通知 --aop:around methodaround pointcut-refpc1/!-- 后置通知 --!-- aop:after-returning methodafterReturn pointcut-refpc1/ --aop:after-returning methodafterReturn pointcut-refpc1 returningmsg/!-- 异常通知 --aop:after-throwing methodafterThrow pointcut-refpc1 throwinge/!-- 最终通知 --aop:after methodafter pointcut-refpc1 //aop:aspect/aop:config/beans applicationContext.xml package cn.tedu.service;
/*** 接口*/
public interface UserService {public String addUser(String name);public void updateUser();public void deleteUser();public void query();
} UserService.java package cn.tedu.service;import org.springframework.stereotype.Service;
/*** UserServiceImple:目标对象*/
Service(userService)
public class UserServiceImple implements UserService {Overridepublic String addUser(String name) {// int i 1/0;System.out.println(增加用户。。);return cjj;}Overridepublic void updateUser() {System.out.println(修改用户。。);}Overridepublic void deleteUser() {System.out.println(删除用户。。);}Overridepublic void query() {System.out.println(查询用户。。);}
} UserServiceImple.java package cn.tedu.aop;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.springframework.stereotype.Component;
/*** FirstAspect:切面代码*/
Component
public class FirstAspect {public void before(JoinPoint jp){ // 可以选择额外的传入一个JoinPoint连接点对象必须用方法的第一个参数接收。Class clz jp.getTarget().getClass();Signature signature jp.getSignature(); // 通过JoinPoint对象获取更多信息String name signature.getName();System.out.println(1 -- before...[clz]...[name]...);}public Object around(ProceedingJoinPoint jp) throws Throwable{System.out.println(1 -- around before...);Object obj jp.proceed(); //--显式的调用目标方法System.out.println(1 -- around after...);return obj;}public void afterReturn(JoinPoint jp, Object msg){Class clz jp.getTarget().getClass();Signature signature jp.getSignature(); String name signature.getName();System.out.println(1 -- afterReturn...[clz]...[name]...[msg]...);}public void afterThrow(JoinPoint jp,Throwable e){Class clz jp.getTarget().getClass();String name jp.getSignature().getName();System.out.println(1 -- afterThrow..[clz]..[name]..e.getMessage());}public void after(JoinPoint jp){Class clz jp.getTarget().getClass();String name jp.getSignature().getName();System.out.println(1 -- after..[clz]..[name]...);}
} FirstAspect.java package cn.tedu.test;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.tedu.service.UserService;
/*** AOPTest测试代码*/
public class AOPTest {Testpublic void test01(){ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml);UserService userService (UserService) context.getBean(userService);String result userService.addUser(cjj); // 一个连接点System.out.println(result);}
} AOPTes.java 五种通知的执行顺序 1.在目标方法没有抛出异常的情况下 前置通知 环绕通知的调用目标方法之前的代码 目标方法 环绕通知的调用目标方法之后的代码 后置通知 最终通知 2.在目标方法抛出异常的情况下 前置通知 环绕通知的调用目标方法之前的代码 目标方法 抛出异常 异常通知 最终通知 3.如果存在多个切面 多切面执行时采用了责任链设计模式。 切面的配置顺序决定了切面的执行顺序多个切面执行的过程类似于方法调用的过程在环绕通知的proceed()执行时去执行下一个切面或如果没有下一个切面执行目标方法从而达成了如下的执行过程 如果目标方法抛出异常 五种通知的常见使用场景 环绕通知 控制事务 权限控制 后置通知 记录日志(方法已经成功调用) 异常通知 异常处理 控制事务 最终通知 记录日志(方法已经调用但不一定成功) 转载于:https://www.cnblogs.com/chuijingjing/p/9806651.html