Spring 从入门到入土——AOP 就这么简单!| 原力计划
作者| 冢狐
责编 | 夕颜
出品 | CSDN博客
什么是AOP?
面向切面编程(Aspect Oriented Programming),通过预编译的方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生泛型,利用AOP可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各个部分的耦合度降低,提高程序的可重用性,同时提高了开发效率。
AOP在Spring中的作用
提供声明式事务;允许用户自定义切面
核心名词
横切关注点:横跨应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的地方,就是横切关注点,如:日志、安全、缓存、事务
切面:横切关注点被模块化的特性对象,即:它是一个类
通知:切面必须要完成的工作。即它是类中的一个方法
目标:被通知对象
代理:向目标对象应用通知以后创建的对象。
切入点:切面通知执行的“地点的定义
连接点:与切入点匹配的执行点
Spring中支持的五种类型的Advice
即Aop在不改变原有代码的情况下,去增加新的功能。
使用Spring实现Aop
使用AOP,需要导入一个依赖包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version>
</dependency>
第一种方式——通过Spring API实现
业务接口和实现类
public interface UserService {public void add();public void delete();public void update();public void search();}
public class UserServiceImpl implements UserService{@Overridepublic void add() {System.out.println("增加用户");}@Overridepublic void delete() {System.out.println("删除用户");}@Overridepublic void update() {System.out.println("更新用户");}@Overridepublic void search() {System.out.println("查询用户");}
}
增强类
前置增强
public class Log implements MethodBeforeAdvice {//method : 要执行的目标对象的方法//objects : 被调用的方法的参数//Object : 目标对象@Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {System.out.println( o.getClass().getName() + "的" + method.getName() + "方法被执行了");}
}
后置增强
public class AfterLog implements AfterReturningAdvice {//returnValue 返回值//method被调用的方法//args 被调用的方法的对象的参数//target 被调用的目标对象@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println("执行了" + target.getClass().getName()+"的"+method.getName()+"方法,"+"返回值:"+returnValue);}
}
去Spring的文件中注册,并实现aop切入实现
<?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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="com.zhonghu.service.UserServiceImpl"/><bean id="log" class="com.zhonghu.log.Log"/><bean id="afterLog" class="com.zhonghu.log.AfterLog"/><!--aop的配置--><aop:config><!--切入点 expression:表达式匹配要执行的方法--><aop:pointcut id="pointcut" expression="execution(* com.zhonghu.service.UserServiceImpl.*(..))"/><!--执行环绕; advice-ref执行方法 . pointcut-ref切入点--><aop:advisor advice-ref="log" pointcut-ref="pointcut"/><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/></aop:config></beans>
测试
public class MyTest {@Testpublic void test(){ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");UserService userService = (UserService) context.getBean("userService");userService.search();}
}
Aop的重要性:很重要,一定要理解其中的思路
Spring的Aop就是将公共的业务(日志、安全)和领域业务结合起来,当执行领域业务时,将会把公共业务加起来,实现公共业务的重复利用,领域业务更加纯粹,程序员只需要专注领域业务。
其本质还是动态代理
第二种方式:自定义类来实现Aop
目标业务不变依旧是userServiceImpl
切入类
public class DiyPointcut {public void before(){System.out.println("---------方法执行前---------");}public void after(){System.out.println("---------方法执行后---------");}}
去spring中配置
<!--第二种方式自定义实现-->
<!--注册bean-->
<bean id="diy" class="com.zhonghu.config.DiyPointcut"/><!--aop的配置-->
<aop:config><!--第二种方式:使用AOP的标签实现--><aop:aspect ref="diy"><aop:pointcut id="diyPonitcut" expression="execution(* com.zhonghu.service.UserServiceImpl.*(..))"/><aop:before pointcut-ref="diyPonitcut" method="before"/><aop:after pointcut-ref="diyPonitcut" method="after"/></aop:aspect>
</aop:config>
测试
public class MyTest {@Testpublic void test(){ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");UserService userService = (UserService) context.getBean("userService");userService.add();}
}
第三种方式——使用注解
注解实现的增强类
package com.zhonghu.config;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect
public class AnnotationPointcut {@Before("execution(* com.zhonghu.service.UserServiceImpl.*(..))")public void before(){System.out.println("---------方法执行前---------");}@After("execution(* com.zhonghu.service.UserServiceImpl.*(..))")public void after(){System.out.println("---------方法执行后---------");}@Around("execution(* com.zhonghu.service.UserServiceImpl.*(..))")public void around(ProceedingJoinPoint jp) throws Throwable {System.out.println("环绕前");System.out.println("签名:"+jp.getSignature());//执行目标方法proceedObject proceed = jp.proceed();System.out.println("环绕后");System.out.println(proceed);}
}
在spring配置文件中,注册bean,并增加支持注解的配置
<!--第三种方式:注解实现-->
<bean id="annotationPointcut" class="com.zhonghu.config.AnnotationPointcut"/>
<aop:aspectj-autoproxy/>
aop:aspectj-autoproxy:说明
通过aop创建的命名空间的<aop:aspectj-autoproxy />声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring 在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的细节已经被<aop:aspectj-autoproxy />隐藏起来了
<aop:aspectj-autoproxy />有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为<aop:aspectj-autoproxy poxy-target-class=“true”/>时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理
进行自动代理的创建工作,但具体实现的细节已经被<aop:aspectj-autoproxy />隐藏起来了。
<aop:aspectj-autoproxy />有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为<aop:aspectj-autoproxy poxy-target-class=“true”/>时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理
版权声明:本文为CSDN博主「冢狐」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/issunmingzhi/java/article/details/106051063
推荐阅读
不知道路由器工作原理?没关系,来这看看!看不懂你捶我 | 原力计划
秋名山老司机从上车到翻车的悲痛经历,带你深刻了解什么是 Spark on Hive!| 原力计划
出道50年+!乘风破浪的编程语言们,能二次翻红吗?
Service Mesh 如何重定义云原生计算?阿里服务网格技术大揭秘
国士无双:卖掉美国房子,回国创办姚班,他只为培养一流的程序员!
万字长文带你入门 GCN
真香,朕在看了!
Spring 从入门到入土——AOP 就这么简单!| 原力计划相关推荐
- 我们已经不用AOP做操作日志了! | 原力计划
来源 | JAVA葵花宝典 责编 | 王晓曼.Carol 头图 | CSDN下载自东方IC 前言 用户在操作我们系统的过程中,针对一些重要的业务数据进行增删改查的时候,我们希望记录一下用户的操作行为 ...
- 盘一盘 Spring 核心技术之依赖注入 | 原力计划
作者 | 麦洛_ 责编 | 夕颜 头图 | CSDN付费下载自视觉中国 出品 | CSDN博客 前言 提起Spring,大家肯定不陌生,它是每一个Java开发者绕不过去的坎.Spring 框架为基于 ...
- ❤️爆肝万字!一文最全总结之Spring从入门到入土❤️(建议收藏)
文章目录 最新更新 前言 1. Spring概述 1.1 介绍 2. IoC入门 2.1 什么是IoC 2.2 IoC入门案例1(基础案例) 2.3 IoC入门案例2(依赖注入) 2.4 IoC入门案 ...
- 一文最全总结之Spring从入门到入土
文章目录 最新更新 前言 1. Spring概述 1.1 介绍 2. IoC入门 2.1 什么是IoC 2.2 IoC入门案例1(基础案例) 2.3 IoC入门案例2(依赖注入) 2.4 IoC入门案 ...
- 一文最全总结之Spring从入门到入土(上)
文章目录 1. Spring概述 1.1 介绍 2. IoC入门 2.1 什么是IoC 2.2 IoC入门案例1(基础案例) 2.3 IoC入门案例2(依赖注入) 2.4 IoC入门案例3(面向接口编 ...
- Spring从入门到入土——Bean的作用域与生命周期
Bean的作用域 在Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean.简单地讲,bean就是由IoC容器初始化.装配及管理的对象 类别 说明 sin ...
- 看完这一篇,你就对 Spring Security 略窥门径了 | 原力计划
作者 | BoCong-Deng 来源 | CSDN 博客,责编 | 夕颜 头图 | CSDN 下载自东方 IC 出品 | CSDN(ID:CSDNnews) 写在前面 开发Web应用,对页面的安全控 ...
- 为什么你学了 N 遍 Spring Boot,至今还是学生项目?你的问题在这里 | 原力计划...
作者 | bugpool 出品 | CSDN博客 为什么你学了n遍<1天精通Spring Boot>,至今还是不精通Spring Boot,甚至还是停留在学生项目?真正要做项目就应该一步到 ...
- spring 依赖注入_Spring从入门到入土——依赖注入(DI)
Dependency Injection 概念 依赖注入(DI) 依赖:指Bean对象的创建依赖于容器.Bean对象的依赖资源 注入:指Bean对象 注入方式 一共有三种:分别是构造器注入:Set注入 ...
最新文章
- mysql数据库导入导出
- document.all和document.layers
- vue中v-bind指令的使用之Vue知识点归纳(七)
- 【离散数学】集合论 第四章 函数与集合(1) 函数定义、递归定义的函数
- 电脑小技巧:怎么取消电脑开机密码
- 《Java从入门到放弃》框架入门篇:在MyEclipse中创建SpringBoot项目
- example包下载
- android倒计时器
- html5 fa图标库,axure官方制作FontAwesome图标元件库V5.5.0版
- 中国电视艺术家协会名誉主席赵化勇一行莅临蓝海彤翔参观指导
- Canvas学习:绘制箭头
- 1小时1篇文学会用python进行AI修复!
- 【专项测试】系统数据迁移
- CSS学习笔记7—盒子模型
- 向oracle中插入图片和读取图片
- 汉诺塔(递归算法)C语言
- App 崩溃(闪退)原因
- Real-Time Rendering——Chapter 7 Advanced Shading
- 手撸一款属于自己的Maven插件,说干就干
- 库克、贝佐斯、扎克伯格和皮查伊的听证会,是美国政府的「数字化削藩」
热门文章
- 基于python的分布式扫描器_基于python的服务器监测系统的设计
- c语言利用栈将字符串逆序输出,【C语言】利用栈将数组中字符串逆序
- 学霸女神冯净冰:我是如何从复旦走到诺奖获得者经济学大会的
- Membership Inference Attacks Against Recommender Systems论文解读
- vue.js php,vue.js去哪下载
- Java集合之LinkedHashMap源码分析
- Ubicomp2018年论文列表
- python练习代码保存
- C/C++字符串输入方法比较(带回车不带回车输入)
- strchr与strstr函数