spring04——AOP

什么是AOP?
AOP:面向切面编程

理解AOP的由来

系统程序的服务,如:事务管理、权限验证、日志记录等需要在每一个核心业务中使用,所以每个核心业务都需要写一遍系统服务代码,所以我们可以使用OOP解决方案,将系统层面代码提取出来,然后在每个业务中调用即可。如图:
oop解决方案
不过OOP方法虽然可以简化代码,但没有解决核心业务中掺杂系统服务代码的问题。
传统的 OOP 程序经常表现出一些不自然的现象,核心业务中总掺杂着一些不相关联的
特殊业务,如日志记录,权限验证,事务控制,性能检测,错误信息检测等等。
这些特殊业务可以说和核心业务没有根本上的关联而且核心业务也不关心它们。而工程师更希望的是这些模块可以实现热插拔特性而且无需把外围的代码入侵到核心模块中使在核心业务中无需掺杂系统层面的代码,但是又带着系统层面的功能

AOP

aop
每个关注点与核心业务模块分离,作为单独的功能,横切几个核心业务模块,这样的做
的好处是显而易见的,每份功能代码不再单独入侵到核心业务类的代码中,即核心模块只需关注自己相关的业务,当需要外围业务(日志,权限,性能监测、事务控制)时,这些外围业务会通过一种特殊的技术自动应用到核心模块中,这些关注点有个特殊的名称,叫做“横切关注点”,上图也很好的表现出这个概念,另外这种抽象级别的技术也叫 AOP(面向切面编程)

AOP 为 Aspect Oriented Programming 的缩写,称为面向切面编程,在程序开发中
主要用来解决一些系统层面上的问题,比如日志,事务,权限等。

AOP 采取横向抽取机制,将分散在各个方法中的重复代码提取出来,然后在程序编译
或者运行时,再将这些提取出来的代码应用到需要执行的地方。

AOP 的本质是拦截方法的,对方法进行增强。如何增强? 通过代理----所以 AOP 的
本质就是代理。

更形象的图片
AOP概念图

AOP 的基本概念:

(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知
(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
(3)Advice(通知):AOP 在特定的切入点上执行的增强处理,有
before,after,afterReturning,afterThrowing,around
(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
(5)AOP 代理:AOP 框架创建的对象,代理就是目标对象的加强。Spring 中的 AOP 代理
可以使 JDK 动态代理,也可以是 CGLIB 代理,前者基于接口,后者基于子类。

AOP 的核心概念:拦截

⚫ 通知 - 定义在哪一个时间点上去做。在类上有方法,执行之前,在方法执行之后,
在方法执行的过程中,在方法执行并成功的返回值以后,在方法抛出异常以后。
⚫ 连接点 – 拦截哪一个类,哪一个方法 。
AOP(拦截) = 通知(时间) + 切点(在哪个类上)
Advisor = Advice + PointCut

Advice --通知

要求用户实现的类/接口 名字 功能
MethodBeforeAdvice 前通知 方法执行前通知
AfterAdvice 后通知 方法执行后通知
AroundAdvice  MethodInterceptor 环绕通知 方法执行的前后分别做一些增强
AfterReturningAdvice 返回后通知 成功返回后(返回值以后通知)
ThrowsAdvice 异常通知 抛出错误以后通知

PointCut –切点的类型

1、基于正则表达式的切点JDKREJPointCut:不学
2、AspectJ基于AOP的切点表达式 AspectJEx***PointCut:重点
切点类型

Spring 中的 aop 代理,可以是 JDK 动态代理,也可是是 CGLIB 代理。

我写在另一篇文章中了,可以搜一下,但我们老师没有讲解,我只是把课件拿来供参考,以后回头再学。
(深思熟虑了一下,这里的两种代理,应该是springaop的底层实现方式,我们的实现方式使用AspectJ来实现)
(然后jdk动态代理有三种实现方式:基于java代码,基于xml配置,基于注解)
(有可能cglib也是这三种)

基于代理类的 AOP 实现(这里我极不确定我的分类是否正确,如果有大神在,希望帮我指正)

两种实现方式:

1、java 代码实现(我们老师说没必要讲,只要理解原理概念,会通过spring开发AOP就够了(通过配置文件进行开发))

在这里我还是粘一下课件

首先创建一个通知

public class MyAdvice implements MethodBeforeAdvice{
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
	// TODO Auto-generated method stub
	System.err.println("方法前:"+arg0.getName()+",拦截的是哪一个类:"+arg2);
	}
}

再创建一个被代理对象

public class Person {
	public void say(){
		System.err.println(" ----- hello every body..");
	}
	public void run(){
		System.err.println("i am running.....");
	}
	public void geeting(){
		System.err.println("大家好同学们");
	)
}

最后写一个aop 的测试类

public void test1() throws Exception {
	//1:声明通知
	Advice advice = new MyAdvice();
	//2:声明切入点
	JdkRegexpMethodPointcut cut = new JdkRegexpMethodPointcut();
	//设置对这个类切入,以下切点是指在com包下的,不管是多么深入的包,只要是peron的方法都拦截
	cut.setPattern("com.*.Person.*");
	//3:将通知+切点=AOP
	Advisor advisor = new DefaultPointcutAdvisor(cut, advice);
	//4:声明代理的Bean
	ProxyFactory proxy = new ProxyFactory(new Person());
	//4.2:设置aop
	proxy.addAdvisor(advisor);
	//5:从代理中获取代理的对象
	Object obj = proxy.getProxy();
	Person pp = (Person) obj;
	pp.say();
	System.err.println("-----------------------------");
	pp.run();
	System.err.println("---------------------------");
	pp.geeting();
}

2、XML 配置方式
连课件也没有

AspectJ开发

AspectJ 是一个基于 Java 语言的 AOP 框架,它提供了强大的 AOP 功能。
使用 AspectJ 实现 AOP 有两种方式:
一种是基于 XML 的声明式 AspectJ
一种是基于注解的声明式 AspectJ

现在我们需要了解三点

1、基于 AspectJ 的切点表达式
2、基于 XML 的声明式 AspectJ
3、基于注解的声明式 AspectJ

篇幅太长,不利于学习,我就把他写在下一篇文章中。

END

猜你喜欢

转载自blog.csdn.net/qq_37989076/article/details/88526874