SpringAOP_构造注入实现


AOP_面向切面编程初步了解

让我们先想象一个场景,你正在编写一个项目,在开发过程中的多个模块都有某段重复的代码,于是你选择将其抽象成一个方法,然后在需要的地方调用这个方法,当需要修改这段代码时只需要修改这个方法就行。有一天,你的Boss给了新的需求,需要再抽象出一个方法,然后再在各个需要这个方法的模块调用这个方法,这可能就让你头疼了,需要修改大量的代码,于是会想,能不能不修改源代码为系统业务添加某种功能呢?幸运的是,AOP可以很好的解决这个问题。

简单介绍

AOP:保证开发者不修改源代码的前提下,去为系统中的业务组件添加某种通用功能,本质是由AOP框架修改业务组件的多个方法的源代码,我们将其分为两类:

  • 静态AOP

    AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的*.class文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。
  • 动态AOP:

    AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP。

详细说明

Spring 的通知类型

名称 标签 说明
前置通知 @Before 用于配置前置通知。指定增强的方法在切入点方法之前执行
后置通知 @AfterReturning 用于配置后置通知。指定增强的方法在切入点方法之后执行
环绕通知 @Around 用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行
异常通知 @AfterThrowing 用于配置异常抛出通知。指定增强的方法在出现异常时执行
最终通知 @After 用于配置最终通知。无论增强方式执行是否有异常都会执行
切面类注解 @Aspect 标注该当前类是一个切面类
断点注解 @Pointcut 使用一个返回值为 void 、方法体为空的方法来命名切入点

实战演练

导入依赖包

    <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("环绕通知");
}
}

创建一个切面类

@Component("VisitAspect")
@Aspect //标注当前myAspect是一个切面类
public class VisitAspect_anno {
// 定义切入点表达式
// 使用一个返回值为 void 、方法体为空的方法来命名切入点
@Pointcut("execution(* Spring_AOP.service.impl.VisitServiceImpl.visit(..))")
private void v1() {
} //前置通知
@Before("v1()")
public void visitBefore(JoinPoint joinPoint) { System.out.println("口令:");
} @After("v1()")
//最终通知,无论是否报错,都执行
public void visitAfter(JoinPoint joinPoint) {
System.out.println("输入完成");
} @AfterReturning("v1()")
//后置通知报错不执行
public void visitSuccess(JoinPoint joinPoint) {
System.out.println("请求成功,欢迎");
} @AfterThrowing(value = "v1()",throwing = "ex")
//异常通知,报错后执行
public void visitThrow(JoinPoint joinPoint, Throwable ex) {
System.out.println("请求失败,拒绝");
} @Around("execution(* Spring_AOP.service.impl.VisitServiceImpl.around())")
//环绕通知,如果报错只执行前一句
public Object visitAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("-------环绕-------");
Object obj = proceedingJoinPoint.proceed();
System.out.println("------------------");
return obj;
}
}

配置xml文件

    <!-- 基于注解的声明式 AspectJ -->
<context:component-scan base-package="Spring_AOP" />
<!-- 启动基于注解的声明式 AspectJ 支持一 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

创建一个测试类

 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

请求失败,拒绝

输入完成

-------环绕-------

环绕通知

-------环绕-------


总结

  • 使用构造注入可以更方便的实现AOP模式,但是同样与设置注入相比各有千秋。

以上就是以注解实现SpringAOP框架构造注入的实现,如有错误,麻烦指出,感谢耐心到现在的朋友ᕕ( ᐛ )ᕗ ---By 不断努力的Yang

SpringAOP_构造注入实现的更多相关文章

  1. Spring 设值注入 构造注入 p命名空间注入

    注入Bean属性---构造注入配置方案 在Spring配置文件中通过<constructor-arg>元素为构造方法传参 注意: 1.一个<constructor-arg>元素 ...

  2. Ioc和Aop扩展--多种方式实现依赖注入(构造注入,p命名空间注入,集合类型注入,注入null和注入空值)

    构造注入 语法: <constructor-arg>    <ref bean="bean的id"/> </constructor-arg> 1 ...

  3. Spring(3.2.3) - Beans(2): 属性注入 & 构造注入

    依赖注入是指程序运行过程中们如果需要另外的对象协作(访问它的属性或调用它的方法)时,无须在代码中创建被调用者,而是依赖于外部容器的注入. 属性注入(Setter Injection) 属性注入是指 I ...

  4. spring 构造注入 异常 Ambiguous constructor argument types - did you specify the correct bean references as constructor arguments

    你可能在做项目的时候,需要在项目启动时初始化一个自定义的类,这个类中包含着一个有参的构造方法,这个构造方法中需要传入一些参数. spring提供的这个功能叫“构造注入”, applicationCon ...

  5. Spring注入值得2种方式:属性注入和构造注入

    Spring是一个依赖注入(控制反转)的框架,那么依赖注入(标控制反转)表现在那些地方了? 即:一个类中的属性(其他对象)不再需要手动new或者通过工厂方法进行创建,而是Spring容器在属性被使用的 ...

  6. Spring接口编程_设值注入和构造注入

    说明: UserManagerImp是设值注入,UserManagerImp2是构造注入 接口不注入,也就是在Spring配置文件中没有接口的<bean>,但是定义的时候是用接口 priv ...

  7. Spring学习(3)---Spring设值注入和构造注入

    (一)设值注入就是指要被注入的类中定义有一个setter()方法,并在参数中定义需要注入的对象.简单的看个例子. 建一个User类: package com.ioc; public class Use ...

  8. 7.28.1 Spring构造注入还是设置注入

    1. 构造方法注入代码如下:public UserManagerImpl(UserDao userDao) {                                              ...

  9. SSM-Spring-04:Spring的DI的构造注入,P命名注入,和集合注入

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- DI和IOC相比,DI更偏向于实现 DI的set方式注入在前面入门案例里有写,所以此处不多啰嗦,直接开搞,先说 ...

随机推荐

  1. 封装fetch请求失败和超时再次请求

    转: 封装fetch请求失败和超时再次请求 function _fetch(fetch_promise, timeout) { var abort_fn = null; //这是一个可以被reject ...

  2. LeetCode-二叉树的镜像

    二叉树的镜像 二叉树的镜像 给定一个二叉树,输出二叉树的镜像. 只需要使用一个简单的递归,分别对左右子树反转后再对当前结点进行反转. #include<iostream> #include ...

  3. rsyslog日志总结

    rsyslog日志总结 一 rsyslog介绍 syslogd被rsyslog取代 将日志写入数据库 可以利用模块和插件控制输入输出 rsyslog程序管理本地和远程日志 安装软件 根据需求修改配置文 ...

  4. vscode动态调试

    前言: 关于vscode动态调试php项目其实在网上有文章,但那些文章或多或少都有些坑点或者转载他人,未经验证过,几度重装系统重新配置的时候在网上看文章配置总是有点问题,所以这次自己写了一篇文章,从头 ...

  5. C#关于个Base64,MD5,16进制的转换

    1,待签名数据以UTF-8的格式转字节流,对字节流进行MD5算法得到的签名字节流,再转换为16进制字符串,即生成了数字签名. byte[] targetData = md5.ComputeHash(S ...

  6. 前端笔记:React的form表单全部置空或者某个操作框置空的做法

    1.全部置空的做法,一般在弹出框关闭后,需要重置该form所有表单: this.props.form.resetFields(); 2.针对某个操作框置空的做法 例如,form表单里有一个部门和一个张 ...

  7. 【odoo14】第十三章、网站开发(对外服务)

    本章我们将介绍一些关于odoo web服务方面的基础知识.进阶的内容,将在第十四章介绍. odoo中的web请求是由python的werkzeug库驱动的.odoo为了操作方便,对werkzeug进行 ...

  8. 修饰符static和abstract

    修饰符static和abstract static static可以修饰类中的方法,属性等,被修饰后的方法和属性可以通过类名直接调用也可以通过对象调用.普通的变量只能通过对象进行调用. 静态方法直接可 ...

  9. android分析之mutex

    Android的锁是对Linux锁的一种包装: // ------------------------------------------------------------------------- ...

  10. Spring基于XML的IoC

    Maven导入Spring依赖 <dependency> <groupId>org.springframework</groupId> <artifactId ...