SpringAOP_设置注入实现
SpringAOP_设置注入实现
AOP_面向切面编程初步了解
让我们先想象一个场景,你正在编写一个项目,在开发过程中的多个模块都有某段重复的代码,于是你选择将其抽象成一个方法,然后在需要的地方调用这个方法,当需要修改这段代码时只需要修改这个方法就行。有一天,你的Boss给了新的需求,需要再抽象出一个方法,然后再在各个需要这个方法的模块调用这个方法,这可能就让你头疼了,需要修改大量的代码,于是会想,能不能不修改源代码为系统业务添加某种功能呢?幸运的是,AOP可以很好的解决这个问题。
简单介绍
AOP:保证开发者不修改源代码的前提下,去为系统中的业务组件添加某种通用功能,本质是由AOP框架修改业务组件的多个方法的源代码,我们将其分为两类:
- 静态AOP
AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的*.class文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。 - 动态AOP:
AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP。
详细说明
Spring 的通知类型
名称 | 标签 | 说明 |
---|---|---|
前置通知 | < aop:before > | 用于配置前置通知。指定增强的方法在切入点方法之前执行 |
后置通知 | < aop:after-returning > | 用于配置后置通知。指定增强的方法在切入点方法之后执行 |
环绕通知 | < aop:around > | 用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行 |
异常通知 | < aop:throwing > | 用于配置异常抛出通知。指定增强的方法在出现异常时执行 |
最终通知 | < aop:after > | 用于配置最终通知。无论增强方式执行是否有异常都会执行 |
实战演练
导入依赖包
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
创建一个增强类以及其接口
增强类接口:
public interface VisitService {
//用于实现前置通知,后置通知,异常通知,最终通知
void visit(String str) throws Exception;
//用于实现环绕通知
void around();
}
增强类:
public class VisitServiceImpl implements VisitService {
//前置,后置,最终,异常通知的增强类
public void visit(String str) throws Exception{
System.out.println(str);
if(!str.equalsIgnoreCase("agree")){
throw new Exception("非法访问");
}
}
//环绕通知的增强类
public void around() {
System.out.println("环绕通知");
}
}
创建一个切面类
public class VisitAspect {
//前置通知
public void visitBefore(JoinPoint joinPoint){
System.out.println("口令:");
}
//最终通知,无论是否报错,都执行
public void visitAfter(JoinPoint joinPoint){
System.out.println("输入完成");
}
//后置通知报错不执行
public void visitSuccess(JoinPoint joinPoint){
System.out.println("请求成功,欢迎");
}
//异常通知,报错后执行
public void visitThrow(JoinPoint joinPoint, Throwable ex){
System.out.println("请求失败,拒绝");
}
//环绕通知,如果报错只执行前一句
public Object visitAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("-------环绕-------");
Object obj = proceedingJoinPoint.proceed();
System.out.println("-------环绕-------");
return obj;
}
}
配置xml文件,需要添加第三方约束
<bean id="userDao" class="Spring_AOP.service.impl.VisitServiceImpl"></bean>
<bean id="aspect" class="Spring_AOP.service.VisitAspect"></bean>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* Spring_AOP.service.impl.VisitServiceImpl.visit(..))"/>
<aop:pointcut id="pointcut1" expression="execution(* Spring_AOP.service.impl.VisitServiceImpl.around())"/>
<aop:aspect ref="aspect">
<aop:before method="visitBefore" pointcut-ref="pointcut"></aop:before>
<aop:after method="visitAfter" pointcut-ref="pointcut"></aop:after>
<aop:after-returning method="visitSuccess" pointcut-ref="pointcut"></aop:after-returning>
<aop:around method="visitAround" pointcut-ref="pointcut1"></aop:around>
<!-- 报错后执行aop:after-throwing -->
<aop:after-throwing method="visitThrow" pointcut-ref="pointcut" throwing="ex"></aop:after-throwing>
</aop:aspect>
</aop:config>
注,对于execution()
1、execution(): 表达式主体 (必须加上execution)。
2、第一个* 号:表示返回值类型,* 号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,cn.smd.service.impl包、子孙包下所有类的方法。
4、第二个* 号:表示类名,* 号表示所有的类。
5、* (..):最后这个星号表示方法名,* 号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
书写的注意事项:execution(* cn.smd.service.impl..(..))
创建一个测试类
public class visitTest {
@Test
public void VisitTest(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext_AOP.xml");
VisitService visitService = app.getBean(VisitService.class);
try {
visitService.visit("agree");
} catch (Exception e) {
e.printStackTrace();
}
try {
visitService.visit("ok");
} catch (Exception e) {
e.printStackTrace();
}
visitService.around();
}
}
测试运行
口令:
agree
请求成功,欢迎
输入完成
口令:
ok
请求失败,拒绝
输入完成
-------环绕-------
环绕通知
-------环绕-------
总结
- SpringAOP进一步降低组件的耦合,实现解耦合
- 可以更好的监控程序,进行权限拦截
- 注:学习AOP设置注入时需要注意出现报错时各个通知的状态
以上就是以注解实现SpringAOP框架设置注入的实现,如有错误,麻烦指出,感谢耐心到现在的朋友ᕕ( ᐛ )ᕗ ---By 不断努力的Yang
SpringAOP_设置注入实现的更多相关文章
- SpringAOP_构造注入实现
SpringAOP_构造注入实现 AOP_面向切面编程初步了解 让我们先想象一个场景,你正在编写一个项目,在开发过程中的多个模块都有某段重复的代码,于是你选择将其抽象成一个方法,然后在需要的地方调用这 ...
- 7.28.1 Spring构造注入还是设置注入
1. 构造方法注入代码如下:public UserManagerImpl(UserDao userDao) { ...
- Spring 3.1新特性之四:p命名空间设置注入(待补充)
https://www.ibm.com/developerworks/cn/java/j-lo-jparelated/ http://www.ibm.com/developerworks/cn/jav ...
- Spring IOC 注入方式
依赖注入通常有如下两种方式: ①设值注入:IOC容器使用属性的Setter方法来注入被依赖的实例. 设值注入是指IOC容器使用属性的Setter方法来注入被依赖的实例.这种注入方式简单.直观,因而在S ...
- 【spring bean】spring中bean的懒加载和depends-on属性设置
项目结构如下: ResourceBean.java代码: package com.it.res; import java.io.File; import java.io.FileNotFoundExc ...
- 轻松了解Spring中的控制反转和依赖注入(一)
我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此,企业级Ja ...
- Spring学习3—控制反转(IOC)Spring依赖注入(DI)和控制反转(IOC)
一.思想理解 Spring 能有效地组织J2EE应用各层的对象.不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调.运行.S ...
- 依赖注入Bean属性
一.Bean属性依赖注入 对于类成员变量,注入方式有三种 •构造函数注入 •属性setter方法注入 •接口注入 Spring支持前两种 1.构造函数 属性注入 使用构造方法注入,在Spring配置文 ...
- 控制反转(IOC)和依赖注入(DI)的区别
IOC inversion of control 控制反转 DI Dependency Injection 依赖注入 要理解这两个概念,首先要搞清楚以下几个问题: 参与者都有谁? 依赖:谁 ...
随机推荐
- ElasticSearch学习笔记(超详细)
文章目录 初识ElasticSearch 什么是ElasticSearch ElasticSearch特点 ElasticSearch用途 ElasticSearch底层实现 ElasticSearc ...
- 人脸检测数据源制作与基于caffe构架的ALEXNET神经网络训练
本篇文章主要记录的是人脸检测数据源制作与ALEXNET网络训练实现检测到人脸(基于caffe). 1.数据获取 数据获取: ① benchmark是一个行业的基准(数据库.论文.源码.结果),例如WI ...
- 剑指 Offer 48. 最长不含重复字符的子字符串 + 动态规划 + 哈希表 + 双指针 + 滑动窗口
剑指 Offer 48. 最长不含重复字符的子字符串 Offer_48 题目详情 解法分析 解法一:动态规划+哈希表 package com.walegarrett.offer; /** * @Aut ...
- 剑指 Offer 41. 数据流中的中位数 + 堆 + 优先队列
剑指 Offer 41. 数据流中的中位数 Offer_41 题目详情 题解分析 本题使用大根堆和小根堆来解决这个寻找中位数和插入中位数的问题. 其实本题最直接的方法是先对数组进行排序,然后取中位数. ...
- HDOJ-1176(数塔问题变形)
免费陷阱 HDOJ-1176 一开始正向推的时候,一直wa,后来采用逆向推得到正确结果. 初始化的时候dp数组都初始化为0. #include<bits/stdc++.h> using n ...
- POJ-1751(kruskal算法)
Highways POJ-1751 注意这里的样例答案也是对的,只是输出顺序改变,但是这也没关系,因为题目加了特殊判断. #include<iostream> #include<cs ...
- vue打开新窗口并且实现传参,有图有真相
我要实现的功能是打开一个新窗口用来展示新页面,而且需要传参数,并且参数不能显示在地址栏里面,而且当我刷新页面的时候,传过来的参数不能丢失,要一直存在,除非我手动关闭这个新窗口,即浏览器的标签页. 通过 ...
- golang操作mysql2
目录 Go操作MySQL 连接 下载依赖 使用MySQL驱动 初始化连接 SetMaxOpenConns SetMaxIdleConns CRUD 建库建表 查询 单行查询 多行查询 插入数据 更新数 ...
- C++高精度计算(大整数类)
Java和Pathon可以不用往下看了 C++的基本数据类型中,范围最大的数据类型不同编译器不同,但是最大的整数范围只有[-2^63-2^63-1](对应8个字节所对应的二进制数大小).但是对于某些需 ...
- 性能追击:万字长文30+图揭秘8大主流服务器程序线程模型 | Node.js,Apache,Nginx,Netty,Redis,Tomcat,MySQL,Zuul
本文为<高性能网络编程游记>的第六篇"性能追击:万字长文30+图揭秘8大主流服务器程序线程模型". 最近拍的照片比较少,不知道配什么图好,于是自己画了一个,凑合着用,让 ...