使用注解的方式编写:@Aspect运用
列子、
public interface Calculator {
// 加
public int add(int i,int j);
// 减
public int sub(int i,int j);
// 乘
public int mul(int i,int j);
//除
public int div(int i,int j);
}
@Service
public class MyMathCalculator implements Calculator {
@Override
public int add(int i, int j) {
int result = i + j;
return result;
}
@Override
public int sub(int i, int j) {
int result = i - j;
return result;
}
@Override
public int mul(int i, int j) {
int result = i * j;
return result;
}
@Override
public int div(int i, int j) {
int result = i / j;
return result;
}
}
/**
* 如何将这个类(切面类)中的这些方法(通知方法)动态的在目标方法运行的各个位置切入
*
*
*/
@Aspect
@Component
public class LogUtils {
@Pointcut("execution(public int com.atguigu.impl.MyMathCalculator.*(..))")
public void MyPoint(){};
/**
*告诉spring每个方法都什么时候运行;
*
* try{
* @Before
* method.invoke(obj,args);
* @AfterReturning
* }catch(e){
* @AfterThrowing
* }finally{
* @After
* }
*
*
*
* 5个通知
* @Before:在目标方法之前运行
* @After:在目标方法结束之后
* @AfterReturning:在目标方法正常返回之后
* @AfterThrowing:在目标方法抛出异常之后运行
* @Around:环绕
*
* //execution(访问权限符 返回值类型 方法签名)
*
*/
// @Before("execution(public int com.apcstudy.aop.impl.MyMathCalculator.*(..))")
@Before(value = "MyPoint()")
public static void logStart(JoinPoint joinPoint){
//获取到目标方法运行是使用的参数
Object[] args = joinPoint.getArgs();
//获取到方法签名
Signature signature = joinPoint.getSignature();
String name = signature.getName();
System.out.println("【"+name+"】方法开始执行,用的参数列表【"+ Arrays.asList(args)+"】");
}
/**
* 告诉Spring这个result用来接收返回值:
* returning="result";
* @param joinPoint
* @param result
*/
@AfterReturning(value = "execution(public int com.apcstudy..impl.MyMathCalculator.*(..))",returning = "result")
public static void logReturn(JoinPoint joinPoint,Object result){
System.out.println("【"+joinPoint.getSignature().getName()+"】方法正常执行完成,计算结果是:"+result);
}
/**
* 细节四:我们可以在通知方法运行的时候,拿到目标方法的详细信息;
* 1)只需要为通知方法的参数列表上写一个参数:
* JoinPoint joinPoint:封装了当前目标方法的详细信息
* 2)、告诉Spring哪个参数是用来接收异常
* throwing="exception":告诉Spring哪个参数是用来接收异常
* 3)、Exception exception:指定通知方法可以接收哪些异常
*
* ajax接受服务器数据
* $.post(url,function(abc){
* alert(abc)
* })
*/
@AfterThrowing(value = "execution(public int com.apcstudy..MyMathCalculator.*(..))",throwing = "exception")
public static void logException(JoinPoint joinPoint,Exception exception){
System.out.println("【"+joinPoint.getSignature().getName()+"】方法执行出现异常了,异常信息是【"+exception+"】:;这个异常已经通知测试小组进行排查");
}
/**
* Spring对通知方法的要求不严格;
* 唯一要求的就是方法的参数列表一定不能乱写?
* 通知方法是Spring利用反射调用的,每次方法调用得确定这个方法的参数表的值;
* 参数表上的每一个参数,Spring都得知道是什么?
* JoinPoint:认识
* 不知道的参数一定告诉Spring这是什么?
* @param joinPoint
* @return
*/
@After("execution(public int com.apcstudy.aop.impl.MyMathCalculator.*(..))")
private int logEnd(JoinPoint joinPoint){
System.out.println("【"+joinPoint.getSignature().getName()+"】方法最终结束了");
return 0;
}
/**
* @throws Throwable
* @Around:环绕 :是Spring中强大的通知;
* @Around:环绕:动态代理;
* try{
* //前置通知
* method.invoke(obj,args);
* //返回通知
* }catch(e){
* //异常通知
* }finally{
* //后置通知
* }
*
* 四合一通知就是环绕通知;
* 环绕通知中有一个参数: ProceedingJoinPoint pjp
*
*环绕通知:是优先于普通通知执行,执行顺序;
*
*[普通前置]
*{
* try{
* 环绕前置
* 环绕执行:目标方法执行
* 环绕返回
* }catch(){
* 环绕出现异常
* }finally{
* 环绕后置
* }
*}
*
*
*[普通后置]
*[普通方法返回/方法异常]
*新的顺序:
* (环绕前置---普通前置)----目标方法执行----环绕正常返回/出现异常-----环绕后置----普通后置---普通返回或者异常
*注意:
*/
@Around("hahaMyPoint()")
public Object myAround(ProceedingJoinPoint pjp) throws Throwable{
Object[] args = pjp.getArgs();
String name = pjp.getSignature().getName();
//args[0] = 100;
Object proceed = null;
try {
//@Before
System.out.println("【环绕前置通知】【"+name+"方法开始】");
//就是利用反射调用目标方法即可,就是method.invoke(obj,args)
proceed = pjp.proceed(args);
//@AfterReturing
System.out.println("【环绕返回通知】【"+name+"方法返回,返回值"+proceed+"】");
} catch (Exception e) {
//@AfterThrowing
System.out.println("【环绕异常通知】【"+name+"】方法出现异常,异常信息:"+e);
//为了让外界能知道这个异常,这个异常一定抛出去
throw new RuntimeException(e);
} finally{
//@After
System.out.println("【环绕后置通知】【"+name+"】方法结束");
}
//反射调用后的返回值也一定返回出去
return proceed;
}
}
public class AOPTest {
ApplicationContext ioc = new ClassPathXmlApplicationContext("conf/applicationContext.xml");
/**
* 通知方法的执行顺序;
*
* try{
* @Before
* method.invoke(obj,args);
* @AfterReturning
* }catch(){
* @AfterThrowing
* }finally{
* @After
* }
*
* 正常执行: @Before(前置通知)=====@After(后置通知)====@AfterReturning(正常返回);
* 异常执行: @Before(前置通知)=====@After(后置通知)===@AfterThrowing(方法异常)
*
*/
@Ignore
public void test01(){
// 一定要从容器中拿到目标对象;注意:如果想要用类型,一定要用他的接口类型,不要用本类;
Calculator calculator = ioc.getBean(Calculator.class);
calculator.add(2, 12);
}
@Test
public void test02(){
// 一定要从容器中拿到目标对象;注意:如果想要用类型,一定要用他的接口类型,不要用本类;
Calculator calculator = ioc.getBean(Calculator.class);
calculator.add(2, 12);
System.out.println("=================");
calculator.div(1, 0);
}
}
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 将接口实现组件加入到容器中 -->
<context:component-scan base-package="com.apcstudy.aop"></context:component-scan>
<!-- 开启基于注解的AOP功能:aop名称空间 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
使用注解的方式编写:@Aspect运用的更多相关文章
- Spring-增强方式注解实现方式
SpringAOP增强是什么,不知道的到上一章去找,这里直接上注解实现的代码(不是纯注解,纯注解后续会有) 创建业务类代码 @Service("dosome")//与配置文件中&l ...
- java web学习总结(二十一) -------------------模拟Servlet3.0使用注解的方式配置Servlet
一.Servlet的传统配置方式 在JavaWeb开发中, 每次编写一个Servlet都需要在web.xml文件中进行配置,如下所示: 1 <servlet> 2 <servlet- ...
- Mybatis框架基于注解的方式,实对数据现增删改查
编写Mybatis代码,与spring不一样,不需要导入插件,只需导入架包即可: 在lib下 导入mybatis架包:mybatis-3.1.1.jarmysql驱动架包:mysql-connecto ...
- JavaWeb学习总结(四十八)——模拟Servlet3.0使用注解的方式配置Servlet
一.Servlet的传统配置方式 在JavaWeb开发中, 每次编写一个Servlet都需要在web.xml文件中进行配置,如下所示: 1 <servlet> 2 <servlet- ...
- Spring+AOP+Log4j 用注解的方式记录指定某个方法的日志
一.spring aop execution表达式说明 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义 ...
- springMvc的注解注入方式
springMvc的注解注入方式 最近在看springMvc的源码,看到了该框架的注入注解的部分觉的有点吃力,可能还是对注解的方面的知识还认识的不够深刻,所以特意去学习注解方面的知识.由于本人也是抱着 ...
- spring schedule定时任务(一):注解的方式
我所知道的java定时任务的几种常用方式: 1.spring schedule注解的方式: 2.spring schedule配置文件的方式: 3.java类继承TimerTask: 第一种方式的实现 ...
- java AOP使用注解@annotation方式实践
java AOP使用配置项来进行注入实践 AOP实际开发工作比较常用,在此使用注解方式加深对面向切面编程的理解 废话不多少,先看下面的实例代码 场景: 1.未满一岁的小孩,在执行方法之前打印:“ ...
- 使用Spring框架入门四:基于注解的方式的AOP的使用
一.简述 前面讲了基于XML配置的方式实现AOP,本文简单讲讲基于注解的方式实现. 基于注解的方式实现前,要先在xml配置中通过配置aop:aspectj-autoproxy来启用注解方式注入. &l ...
- 基于注解的方式管理Bean
--------------------siwuxie095 基于注解的方式管理 Bean (一)准备 ...
随机推荐
- lagrange 插值做题记录
插值在OI中的应用 - Grice - 博客园 lagrange 插值笔记 - 洛谷专栏 P5850 calc加强版 - 洛谷 Problem - F - Codeforces 2025oifc202 ...
- 一种把dump里连续的内存保存到文件的方法
前几天调试一个崩溃,截到一个full dump文件,显示一个视频帧数据转换有问题.从调用栈可以看到完整的帧数据. 然后我就想把这个数据保存下来,再构造崩溃场景,VS没有提供把内存dump为文件的功能. ...
- JMeter组件的执行顺序和作用域
组件介绍 测试计划:jmeter的起点和容器 线程组:代表一定的虚拟用户 取样器:发送请求的最小单元 逻辑控制器:控制组件的执行顺序 前置处理器:在请求之前的操作 后置处理器:在请求之后的操作 断言: ...
- linux ubuntu更改软件源
更换步骤 sudo cp /etc/apt/sources.list /etc/apt/sources.list.back sudo vim /etc/apt/sources.list 替换为下面内容 ...
- 【忍者算法】从生活场景理解链表反转:最重要的基础算法|LeetCode第206题 反转链表
从生活场景理解链表反转:最重要的基础算法 为什么这道题如此重要 反转链表看似简单,却是链表操作的基石.就像建房子要先打好地基,做复杂的链表操作前必须深刻理解反转原理.无数高频面试题都建立在这个基础之上 ...
- [BZOJ3786] 星系探索 题解
题目链接:\(BZOJ\) 本题通过 \(dyf\_DYF\) 的题解理解 \(ETT\),代码则借鉴 \(lcyfrog\) 的题解,图片则使用了何太狼的题解.在此笔者感谢这三位神犇. 声明变量: ...
- warning C291: not every exit path returns a value 在switch分支中使用return
switch(data) { case 1: ...
- Dotfuscator混淆时的配置信息
这个是64位的Framework
- 如何让N1盒子、机顶盒开机从优盘启动进入刷机流程
疑难解答加微信机器人,给它发:进群,会拉你进入八米交流群 机器人微信号:bamibot 简洁版教程访问:https://bbs.8miyun.cn 准备阶段 1.下载我的从优盘启动的工具包 2.确认你 ...
- Java01 - Scanner对象
简介 之前我们学的基本语法中并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入.java.util.Scanner是Java5的新特征,我们可以通过Scanner ...