AOP是面向切面编程,区别于oop,面向对象,一个是横向的,一个是纵向。

主要解决代码分散和混乱的问题。

1.概念:

切面:实现AOP共有的类

通知:切面类中实现切面功能的方法

连接点:程序被通知的特定位置

切点:连接点的定义

代理:向目标应用通知而产生的对象

2.配置

 

AOP的实现的基本要求:通过接口创建目标的代理。

1。首先是配置文件,2。然后启动扫描器<context:component-scan>和启动AOP注解支持<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

3.之后再逻辑方法类上定义容器管理@Component(“名称”)若不写名称,则默认是类名首字母小写的名字。

3.定义切面类

定义容器管理@Component和@Aspect//切面类

4.定义通知

通知可分为@before前置通知、@After后置通知、@AfterReturning返回通知、@AfterThrowing异常通知、@Around环绕通知。

前置通知:

在方法执行前执行,参数JoinPoint,代表连接点

可以得到参数列表和方法名

通过getNmae和        getAtgs,反回的是object[]类型

后置通知;在方法之后执行,同样可以获得参数列表和方法名

异常通知:

throwing=“接受异常对象规定参数”

 环绕通知:

5.定义切点表达式

@通知类型注解(pointCut=“execution(修饰符的返回值类型 包名.类名.方法名(参数类型))”)

6.公共切点@Pioneertcut

之后再调用切点表达式的时候直接写:通知类型(“公共切点表达式的类名piontCut”)

接口=============================

package com.hanqi.test;

import org.springframework.stereotype.Component;

public interface I_jsq {

	double add(double a ,double b);
double div(double a ,double b); }

  实现类业务逻辑类=========

package com.hanqi.test;

import org.springframework.stereotype.Component;

@Component("my1")//容器管理
public class Myjsq implements I_jsq { //连接点
@Override
public double add(double a, double b) {
//前置通知的连接点 //日志记录
// System.out.println("日志:a = "+a+" ,b = "+b);
System.out.println(a+"+"+b+"="+(a+b)); if(a < 0)
{
throw new RuntimeException("运行时异常");
}
return(a+b);
//后置通知的连接点
}
//连接点
@Override
public double div(double a, double b) {
//日志记录
//System.out.println("日志:a = "+a+" ,b = "+b); //检查
// if(b==0)
// {
// System.out.println("b不能是0");
// return -1;
// }
// else
// {
System.out.println(a+"/"+b+"="+(a/b));
return (a/b); //}
} }

  切面类================

package com.hanqi.test;

import java.util.Arrays;
import java.util.List; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; //切面类
@Component//容器管理
@Aspect//切面类
@Order(1)
public class LogAspect { //定义公共切点
@Pointcut("execution(* com.hanqi.test.I_jsq.*(..))")
public void pointCut()
{ } //前置通知@Before
@Before("pointCut()")//引用公共切点
public void beforeLog(JoinPoint jp)//通知 JoinPoint表示连接点
{
//连接点的方法名
String ms = jp.getSignature().getName(); //连接点方法的参数
List<Object> ls = Arrays.asList(jp.getArgs()); System.out.println("前置日志,方法名 = "+ms+" 参数列表= "+ls);
} //后置通知
@After("pointCut()")
public void afterLog(JoinPoint jp)
{
//连接点的方法名
String ms = jp.getSignature().getName(); //连接点方法的参数列表
List<Object> ls = Arrays.asList(jp.getArgs()); System.out.println("后置日志,方法名 = "+ms+" 参数列表= "+ls);
} //返回通知
//@AfterReturning(pointcut="execution(* com.hanqi.test.I_jsq.*(..))" ,returning="rtn")
@AfterReturning(pointcut="pointCut()" ,returning="rtn")
public void returningLog(double rtn)
{
//接收返回值
System.out.println("返回值="+rtn);
} //异常通知
@AfterThrowing(pointcut="pointCut()" , throwing="msg")
public void errorLog(Exception msg)
{
System.out.println("异常通知="+msg.getMessage());
} //环绕通知
@Around("pointCut()")//切点表达式,第一个*表示返回类型,第二个*表示方法名
public Object aroundLog(ProceedingJoinPoint pjp)
{
Object rtn= null;
//连接点的方法名
String ms = pjp.getSignature().getName(); //连接点方法的参数
List<Object> ls = Arrays.asList(pjp.getArgs());
//实现四种通知
//1.前置通知
System.out.println("这是环绕通知的前置通知,方法名= "+ms+" 参数="+ls); //调用目标方法
try { rtn= pjp.proceed(); //3.返回通知
System.out.println("这是环绕通知的返回通知,返回值="+rtn ); } catch (Throwable e) {
//4.异常通知
System.out.println("这是环绕通知的异常通知,异常信息="+e.getMessage());
e.printStackTrace();
}
finally
{
//2.后置通知
System.out.println("这是环绕通知的后置通知");
} return rtn;
}
}
package com.hanqi.test;

import java.util.Arrays;
import java.util.List; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
// 切面类
@Component
@Aspect
@Order(2)
public class CheckAspect { //前置通知
//@Before("execution(* com.hanqi.test.Myjsq.div(double,double))")
@Before("LogAspect.pointCut()")//重用切点表达式
public void beforeCheck(JoinPoint jp)
{
//获取参数
Object[] ob = jp.getArgs(); if((Double.parseDouble(ob[1].toString()))== 0)
{
System.out.println("参数不能等于0");
System.out.println("1=="+Double.parseDouble(ob[1].toString()));
System.out.println("0=="+Double.parseDouble(ob[0].toString()));
}
} }

  测试类

package com.hanqi.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestMain { public static void main(String[] args) {
// TODO 自动生成的方法存根
//I_jsq jsq1 = new Myjsq(); ApplicationContext ac =
new ClassPathXmlApplicationContext("app.xml"); I_jsq jsq1 =(I_jsq)ac.getBean("my1");//通过接口创建代理对象 jsq1.add(123, 456); jsq1.div(200, 0); } }

  

  

Spring-AOP面向切面编程的更多相关文章

  1. 详细解读 Spring AOP 面向切面编程(二)

    本文是<详细解读 Spring AOP 面向切面编程(一)>的续集. 在上篇中,我们从写死代码,到使用代理:从编程式 Spring AOP 到声明式 Spring AOP.一切都朝着简单实 ...

  2. 浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~

    简介 我们都知道,Spring 框架作为后端主流框架之一,最有特点的三部分就是IOC控制反转.依赖注入.以及AOP切面.当然AOP作为一个Spring 的重要组成模块,当然IOC是不依赖于Spring ...

  3. spring AOP面向切面编程学习笔记

    一.面向切面编程简介: 在调用某些类的方法时,要在方法执行前或后进行预处理或后处理:预处理或后处理的操作被封装在另一个类中.如图中,UserService类在执行addUser()或updateUse ...

  4. 【Spring系列】Spring AOP面向切面编程

    前言 接上一篇文章,在上午中使用了切面做防重复控制,本文着重介绍切面AOP. 在开发中,有一些功能行为是通用的,比如.日志管理.安全和事务,它们有一个共同点就是分布于应用中的多处,这种功能被称为横切关 ...

  5. 从源码入手,一文带你读懂Spring AOP面向切面编程

    之前<零基础带你看Spring源码--IOC控制反转>详细讲了Spring容器的初始化和加载的原理,后面<你真的完全了解Java动态代理吗?看这篇就够了>介绍了下JDK的动态代 ...

  6. Spring AOP面向切面编程详解

    前言 AOP即面向切面编程,是一种编程思想,OOP的延续.在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等.在阅读本文前希望您已经对Spring有一定的了解 注:在能对代码进行添 ...

  7. Spring AOP 面向切面编程相关注解

    Aspect Oriented Programming 面向切面编程   在Spring中使用这些面向切面相关的注解可以结合使用aspectJ,aspectJ是专门搞动态代理技术的,所以比较专业.   ...

  8. Spring AOP 面向切面编程入门

    什么是AOP AOP(Aspect Oriented Programming),即面向切面编程.众所周知,OOP(面向对象编程)通过的是继承.封装和多态等概念来建立一种对象层次结构,用于模拟公共行为的 ...

  9. 详细解读 Spring AOP 面向切面编程(一)

    又是一个周末, 今天我要和大家分享的是 AOP(Aspect-Oriented Programming)这个东西,名字与 OOP 仅差一个字母,其实它是对 OOP 编程方式的一种补充,并非是取而代之. ...

  10. Spring Aop面向切面编程&&自动注入

    1.面向切面编程 在程序原有纵向执行流程中,针对某一个或某一些方法添加通知,形成横切面的过程叫做面向切面编程 2.常用概念 原有功能:切点,pointcut 前置通知:在切点之前执行的功能,befor ...

随机推荐

  1. golang笔记——函数与方法

    如果你遇到没有函数体的函数声明,表示该函数不是以Go实现的. package math func Sin(x float64) float //implemented in assembly lang ...

  2. tyvj1113 魔族密码

    描述     风之子刚走进他的考场,就……    花花:当当当当~~偶是魅力女皇——花花!!^^(华丽出场,礼炮,鲜花)    风之子:我呕……(杀死人的眼神)快说题目!否则……-_-###    花 ...

  3. #define #include #undef的其中一个用法(目的)

    一.背景 最近在跟一段系统级的代码,和原来单纯的下位机代码相比,真的是刘姥姥进大观园--看花了眼.相较于 之前所常见的各种下位机代码,系统级代码常常会出现深层次结构体嵌套,结构体内的各种回调函数导致对 ...

  4. 【荐2】Total Commander 7.57 配置选项 个性化设置备份,,,开启时如何自动最大化???(二)

    最近安装了下新版的“Total Commander 7.56”,发现它的默认设置是如此的不好用,现把对其个性化设置备份如下(符合大部分用户的操作习惯): 默认打开Total Commander 7.5 ...

  5. 编译器 cc、gcc、g++、CC 的区别

    gcc 是GNU Compiler Collection,原名为Gun C语言编译器,因为它原本只能处理C语言,但gcc很快地扩展,包含很多编译器(C.C++.Objective-C.Ada.Fort ...

  6. Newton's method 分析

    大家都知道对于合理的函数和合理的值域牛顿迭代法是二次收敛(quadratic covergence)的(收敛速度定义见 https://en.wikipedia.org/wiki/Rate_of_co ...

  7. 【Network】Calico, Flannel, Weave and Docker Overlay Network 各种网络模型之间的区别

    From the previous posts, I have analysed 4 different Docker multi-host network solutions - Calico, F ...

  8. c/c++与函数有关的优化

    一.函数调用的优化 调用函数需要对内存进行多次访问,因此对函数的调用通常很费时,容易造成程序效率低下: 在函数调用过程中,如果每一次函数的调用结果都相同且需要多次调用时,可以将几次调用的结果进行多次累 ...

  9. HTML是什么?如何使用?

    ①我们首先打开桌面DW网页开发器. 也可以是其他的开发器. ②打开之后那么我们创建一个新的文档: 点击创建之后出现下图: 一般我们不管用哪种网页开发器,都会最先呈现上图的状态,那么下面来解读一下这些文 ...

  10. C实现栈和队列

    这两天再学习了数据结构的栈和队列,思想很简单,可能是学习PHP那会没有直接使用栈和队列,写的太少,所以用具体代码实现的时候出现了各种错误,感觉还是C语言功底不行.栈和队列不论在面试中还是笔试中都很重要 ...