【总结】spring aop
1.aop简介
AOP的全称是Aspect Oriented Programming,面向切面编程。它的主要思想是在程序正常执行的某一个点切进去加入特定的逻辑。AOP框架中对AOP支持最完整的是Aspectj,Spring Aop是基于Aspectj实现的专门针对于Spring自身支持的Aop,它的功能没有Aspectj那么完整,它只作用于Spring bean容器中bean对象的某个方法的执行。正如Spring官方文档所描述的那样,Spring Aop与Aspectj不是竞争关系,而是相互补充、相互完善的这么一个关系
1.1.基本原理
AOP框架的基本原理基本上都是通过代理的方式对目标对象达到切入式的切面编程的效果,Spring Aop也不例外。Spring Aop只能对它自身bean容器中定义的bean对象进行代理,这算是Spring Aop的一个限制,如果你的项目中不使用Spring的IOC,使用Spring的Aop显然是有点不那么合适的。Spring Aop中使用的代理有两种方式,一种是Jdk的动态代理,另一种是基于CGLIB实现的代理,当我们的bean对象实现了某一接口后,Spring默认将采用Jdk动态代理,当我们的bean对象没有实现接口时,默认将采用CGLIB代理,Spring也支持我们在bean对象实现了接口时也强制的使用CGLIB代理。Spring的Bean容器在初始化bean对象的时候就会判断对应的bean是否需要进行切面编程,即是否需要对其进行代理,如果需要,则初始化的时候就会把它初始化为一个代理对象。下面基于Jdk来看一个简单的示例,假设我们定义了如下这样一个代理工厂,其可以将一个普通的对象基于其实现的接口利用Jdk动态代理机制生成对应的代理对象。具体代码和说明请看如下代码,其中我们可以在目标对象执行特定的方法时加入一些特定的处理逻辑
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
private static ProxyFactory instance = new ProxyFactory();
private ProxyFactory() {}
public static ProxyFactory getInstance() {
return instance;
}
@SuppressWarnings("unchecked")
public <T> T create(final T t) {
return (T) Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), new InvocationHandler() {
/**
* 当使用创建的代理对象执行其中的方法时,都会转换为调用与代理对象绑定的InvocationHandler对象的invoke方法,
* 这样我们就可以在这个方法里面对调用情况进行一些特定的处理逻辑
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("正在调用的方法是:" + method);
//1、加入对调用方法前的处理逻辑
//...
Object result = null;
try {
//2、正常的调用目标对象的目标方法
result = method.invoke(t, args);
//3、可加入正常调用后的处理逻辑
//...
} catch (Exception e) {
//4、可加入目标对象的方法调用抛出异常后的处理逻辑
//..
} finally {
//5、可加入目标对象的方法执行完成后的处理逻辑,此逻辑不论是否抛出异常都将执行
}
return result;
}
});
}
}
@Test
public void test1() {
ProxyFactory proxyFactory = ProxyFactory.getInstance();
//创建一个实现了UserService接口的对象
UserService userService = new UserServiceImpl();
//创建一个基于userService对象的代理对象
UserService proxy = proxyFactory.create(userService);
//调用代理对象的某个方法
User user = proxy.findById(1);
System.out.println(user);
}
上述只是一个简单的示例,只是为了说明Spring Aop的大体原理,实际上Spring Aop的代理逻辑比这个要复杂很多,在初始化bean后它需要判断该bean是否需要创建代理对象,这通常都是BeanPostProcessor的功能。
1.2基本概念
(1)Aspect:切面类,是面向切面编程的主体类,用以定义Pointcut和Advice这样的对应关系。
(2)Join Point:切入点,程序运行的某一个点,比如执行某个方法,在Spring AOP中Join Point总是表示一个方法的执行。
(3)Advice:切面类Aspect需要在Join Point处执行的操作。Advice的类型主要包括Before、After和Around三种。包括Spring在类的很多AOP框架都会把Advice以类似于Interceptor(拦截器)的形式进行封装,然后在每个Join Point的前后都可以包含一个Interceptor链,即可以进行多个操作处理。
(4)Pointcut:用来定义匹配的Join Point的,它是一个表达式。它往往会跟Advice绑定在一起,用以指定需要在Pointcut表达式匹配的Join Point执行的操作。采用Pointcut表达式来匹配Join Point是AOP中一个非常重要的概念,它能够使得我们的Advice能够比较独立,即一个Advice可以同时服务于多个JoinPoint。Spring AOP默认采用Aspectj(AOP的始祖)的Pointcut表达式。
(5)Target Object:目标对象,表示Aspect正在处理的对象。因为Spring AOP是基于运行时代理实现的,所以这个对象永远都是一个代理对象。
(6)Aop Proxy:由AOP框架创建的一个代理对象。在Spring AOP中这个代理对象将由JDK代理(基于接口)或CGLIB代理(基于Class)生成。
(7)Weaving:表示编织的意思。用以将切面类Aspect与目标对象联系在一起的这么一个动作,所形成的结果就是在Pointcut所指定的Join Point执行时由Aspect对目标对象执行特定的Advice。AOP框架中的Weaving动作可以发生在编译时、类装载时和运行时,Spring AOP的Weaving动作是发生在运行时。
1.2.1Advice类型
Advice的类型主要有Before、After和Around三种,Before作用于JoinPoint执行前,After作用于JoinPoint执行后(After类型还可以细分),Around则可作用于JoinPoint执行前后,且JoinPoint的执行需要在Around类型的Advice中进行调用,具体如下:
Before:Before类型的Advice将在Join Point执行前运行,除非在运行时抛出一个异常,否则Before类型的Advice不会阻止Join Point的运行。
After Return:After Return类型的Advice将在Join Point正常执行完成(return)后运行,即Join Point的运行没有抛出对外的异常后返回的。
After Throwing:After Throwing类型的Advice将在Join Point抛出对外的异常后运行。
After (finally):After类型的Advice不论Join Point的执行结果如何都将运行。
Around:Around类型的Advice将围绕一个Join Point执行,它既可以在Join Point执行前执行特定的逻辑,也可以在Join Point执行后执行特定的逻辑,还可以控制Join Point是否执行、抛出异常、修改返回值等。
2.基于Aspectj注解的Spring Aop简单实现
Spring Aop是基于Aop框架Aspectj实现的,它不是完完全全的对Aspectj框架进行扩展和改造,而是利用Aspectj里面的一些功能来实现自己的Aop框架,其中就包括对Aspectj提供的注解的解析。之前已经提过Spring Aop和Aspectj实现的Aop之间的差别,这里就不再赘述。本文主要描述的是如何利用Aspectj提供的注解来实现Spring Aop功能,旨在让大家对Spring Aop、对使用Aspectj注解开发Spring Aop有一个初步印象
2.1启用对Aspectj注解的支持
(1)配置文件方式:当我们的Spring配置是以配置文件为主时,我们可以通过在Spring的配置文件中引入aop相关的schema,然后通过aop:aspectj-autoproxy/来启用对Aspectj注解的支持
<!-- 启用对Aspectj注解的支持 -->
<aop:aspectj-autoproxy/>
(2)注解方式
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
2.2定义切面类
@Aspect
@Component
public class MyAspect {
@Pointcut("execution(* add(..))")
private void pointcut() {}
@Before("com.elim.test.spring.aop.MyAspect.pointcut()")
private void before(JoinPoint joinPoint) {
System.out.println(joinPoint.getTarget() + "----------------------Before---------------------");
}
}
【总结】spring aop的更多相关文章
- 学习AOP之深入一点Spring Aop
上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...
- 学习AOP之认识一下Spring AOP
心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...
- spring aop
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将 ...
- spring aop注解方式与xml方式配置
注解方式 applicationContext.xml 加入下面配置 <!--Spring Aop 启用自动代理注解 --> <aop:aspectj-autoproxy proxy ...
- 基于Spring AOP的JDK动态代理和CGLIB代理
一.AOP的概念 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...
- Spring AOP详解
一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...
- Spring AOP实例——异常处理和记录程序执行时间
实例简介: 这个实例主要用于在一个系统的所有方法执行过程中出线异常时,把异常信息都记录下来,另外记录每个方法的执行时间. 用两个业务逻辑来说明上述功能,这两个业务逻辑首先使用Spring AOP的自动 ...
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- 从零开始学 Java - Spring AOP 实现主从读写分离
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- 从零开始学 Java - Spring AOP 拦截器的基本实现
一个程序猿在梦中解决的 Bug 没有人是不做梦的,在所有梦的排行中,白日梦最令人伤感.不知道身为程序猿的大家,有没有睡了一觉,然后在梦中把睡之前代码中怎么也搞不定的 Bug 给解决的经历?反正我是有过 ...
随机推荐
- 我给VSCode报了个bug,微软工程师竟然凌晨回复了...
柠檬哥整理了50本计算机相关的电子书,关注公众号「后端技术学堂」,回复「1024」即可获取,回复「进群」拉你进读者技术交流群. 本文首发个人微信公众号,欢迎围观点击阅读原文 最近遇到一个有意思的bug ...
- Go 基本类型
整形 标准整形 标准整形是按长度进行分类的,其中uint8为byte型,int16为C语言中的short型,int64为C语言中的long类型. 类型 描述 uint8 无符号 8位整型 (0 到 2 ...
- JD-GUI反编译jar包为Java源代码
程序员难免要借鉴其他java工程的代码.可有时只能拿到.calss文件,jar包或者war包,这个时候要求程序员能熟练的将这些类型文件反编译为Java代码并形成可编译运行的项目.本文介绍的反编译工具是 ...
- 046 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 08 for循环的注意事项
046 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 08 for循环的注意事项 本文知识点:for循环的注意事项 for循环的注意事项 for循环有3个 ...
- HarmonyOS 润和 HiSpark开发套件 免费领!
让人期盼已久的HarmonyOS 2.0终于在9月10日正式上线啦! 这是一件让众多开发者关注的大事件! 相信不少开发者都已经迫不及待的想上手实操了, 为了满足大家的好奇心, 也希望能有更多开发者了解 ...
- Docker笔记2:Docker 镜像仓库
Docker 镜像的官方仓库位于国外服务器上,在国内下载时比较慢,但是可以使用国内镜像市场的加速器(比如阿里云加速器)以提高拉取速度. Docker 官方的镜像市场,可以和 Gitlab 或 GitH ...
- Python库之SQLAlchemy
一.SQLAlchemy简介 1.1.SQLAlchemy是什么? sqlalchemy是一个python语言实现的的针对关系型数据库的orm库.可用于连接大多数常见的数据库,比如Postges.My ...
- golang 爬取百度贴吧绝地求生页面
package main import ( "github.com/antchfx/htmlquery" "io" "net/http" & ...
- linux(centos8):firewalld的运行时日志配置
一,firewalld配置日志的用途: 在生产环境中,firewalld的默认配置是不记录日志 我们通过日志记录下防火墙过滤时拒绝的非法ip, 可以主动把这些有攻击性的ip加入到黑名单, 防患于未然 ...
- spring-boot-route(二十)Spring Task实现简单定时任务
Spring Task是Spring 3.0自带的定时任务,可以将它看作成一个轻量级的Quartz,功能虽然没有Quartz那样强大,但是使用起来非常简单,无需增加额外的依赖,可直接上手使用. 一 如 ...