首页 > 其他分享 >Spring的AOP简介和Spring中的通知使用方法以及异常

Spring的AOP简介和Spring中的通知使用方法以及异常

时间:2022-11-30 16:09:25浏览次数:44  
标签:Object return String Spring AOP hw 简介 通知 public


AOP中关键性概念

连接点(Joinpoint):程序执行过程中明确的点,如方法的调用,或者异常的抛出.

目标(Target):被通知(被代理)的对象

注1:完成具体的业务逻辑

通知(Advice):在某个特定的连接点上执行的动作,同时Advice也是程序代码的具体实现,例如一个实现日志记录的代码(通知有些书上也称为处理)

注2:完成切面编程

代理(Proxy):将通知应用到目标对象后创建的对象(代理=目标+通知),

             例子:外科医生+护士

 

注3:只有代理对象才有AOP功能,而AOP的代码是写在通知的方法里面的

切入点(Pointcut):多个连接点的集合,定义了通知应该应用到那些连接点。

      (也将Pointcut理解成一个条件 ,此条件决定了容器在什么情况下将通知和目标组合成代理返回给外部程序)

适配器(Advisor):适配器=通知(Advice)+切入点(Pointcut)

 

如何实现AOP

目标对象只负责业务逻辑代码

通知对象负责AOP代码,这二个对象都没有AOP的功能,只有代理对象才有

 

接下来贴上案例代码来实现通知:

biz

public interface IBookBiz {
// 购书
public boolean buy(String userName, String bookName, Double price);

// 发表书评
public String comment(String userName, String comments);
}

biz实现

public class BookBizImpl implements IBookBiz {

public BookBizImpl() {
super();
}

public boolean buy(String userName, String bookName, Double price) {
// 通过控制台的输出方式模拟购书 如果价格不对将会触发异常,导致程序停止,但是触发前的事件依然会执行
if (null == price || price <= 0) {
throw new PriceException("book price exception");
}
System.out.println(userName + " buy " + bookName + ", spend ASD " + price);
return true;
}

public String comment(String userName, String comments) {
// 通过控制台的输出方式模拟发表书评
System.out.println(userName + " say:" + comments);
return "123";
}

}

然后我们写一个前后置通知的类

/**
* @program: Maven
* @description: 前置后置通知
* @author: hw
* MethodBeforeAdvice 为前置通知的接口 AfterReturningAdvice为后置通知接口
**/
public class MyMethodBeforeAdvice implements MethodBeforeAdvice, AfterReturningAdvice {
/**
* @Description: 前置通知方法
* @Param: [method, objects, o]
* @return: void
* @Author: hw
*/
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
//类名
String name = o.getClass().getName();
//方法名
String name1 = method.getName();
//参数
String s = Arrays.toString(objects);
System.out.println("前置类名" + name + "方法名" + name1 + "参数" + s);
}

/**
* @Description: 后置通知方法
* @Param: [o, method, objects, o1]
* @return: void
* @Author: hw
*/
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
//类名
String name = o1.getClass().getName();
//方法名
String name1 = method.getName();
//参数
String s = Arrays.toString(objects);
System.out.println("后置类名" + name + "方法名" + name1 + "参数" + s+"返回值"+o);
}

}

这是环绕通知的类,也就是即会在方法执行前执行也会在方法执行后执行,概念像struts的拦截器

/**
* @program: Maven
* @description: 环绕通知
* @author: hw
**/
public class MyMethodInterceptor implements MethodInterceptor {
/**
* @Description: 环绕通知, 前后都执行
* @Param: [methodInvocation]
* @return: java.lang.Object
* @Author: hw
* @Date: 2018/12/5
*/
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
//执行前
//类名
String name = methodInvocation.getThis().getClass().getName();
//方法名
String name1 = methodInvocation.getMethod().getName();
//参数
String s = Arrays.toString(methodInvocation.getArguments());
System.out.println("环绕前"+ name + "方法名" + name1 + "参数" + s);
//执行后通知以下面这行代码分割
Object proceed = methodInvocation.proceed();//返回值
//后置通知
System.out.println("环绕后" + name + "方法名" + name1 + "参数" + s+"返回值"+proceed);
return proceed;
}
}

异常类

/**
* @program: Maven
* @description: 异常
* @author: hw
**/
public class MyThrowsAdvice implements ThrowsAdvice {
/** @Description: 这个方法需要手写出来,并且方法名必须是这个,但是可以通过方法重构使用多个方法
* @Param: [ex]
* @return: void
* @Author: hw
*/
public void afterThrowing(PriceException ex) {
System.out.println("价格异常");
}
}
/**
* @Description: 异常类
* @Param:
* @return:
* @Author: hw
*/
public class PriceException extends RuntimeException {

public PriceException() {
super();
}

public PriceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}

public PriceException(String message, Throwable cause) {
super(message, cause);
}

public PriceException(String message) {
super(message);
}

public PriceException(Throwable cause) {
super(cause);
}

}

接下来是我们最后的配置文件

<!--aop-->
<!--目标-->
<bean class="com.hw.two.biz.impl.BookBizImpl" name="bookBiz"></bean>
<!--前置通知 和后置通知-->
<bean class="com.hw.two.advice.MyMethodBeforeAdvice" name="MymethodBeforeAdvice"></bean>
<!--环绕通知-->
<bean class="com.hw.two.advice.MyMethodInterceptor" name="myinterceptor"></bean>
<!--异常-->
<bean class="com.hw.two.advice.MyThrowsAdvice" name="throwsAdvice"></bean>
<!--过滤通知-->
<bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
name="pointcutAdvisor">
<!--配置需要过来的通知-->
<property name="advice" ref="MymethodBeforeAdvice"></property>
<!--匹配该正则,符合的时候才使用通知-->
<property name="pattern" value=".*buy"></property>
</bean>
<!--代理工厂-->
<bean class="org.springframework.aop.framework.ProxyFactoryBean" name="bookProxy">
<!--设置目标-->
<property name="target" ref="bookBiz"></property>
<!--配置接口 填入目标实现的接口 因为接口可以多实现,所以标签为list-->
<property name="proxyInterfaces">
<list>
<value>com.hw.two.biz.IBookBiz</value>
</list>
</property>
<!--目标通知-->
<property name="interceptorNames">
<list>
<!--前后通知-->
<!--<value>MymethodBeforeAdvice</value>-->
<!--过滤通知-->
<value>pointcutAdvisor</value>
<!--环绕通知-->
<value>myinterceptor</value>
<!--异常-->
<value>throwsAdvice</value>
</list>
</property>
</bean>

测试类

/**
* @program: Maven
* @description: 通知测试
* @author: hw
**/
public class AdviceTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-context.xml");
Object bookProxy = applicationContext.getBean("bookProxy");
IBookBiz biz= (IBookBiz) bookProxy;
biz.buy("猴子","升序",12.5);
System.out.println();
biz.comment("猴子","sss");
}
}

结果

Spring的AOP简介和Spring中的通知使用方法以及异常_类名

大多注释都写在代码中,如有什么问题,欢迎下方留言讨论

标签:Object,return,String,Spring,AOP,hw,简介,通知,public
From: https://blog.51cto.com/u_15897407/5899826

相关文章

  • 基于SpringBoot+Layui的物业管理系统【完整项目源码】
    使用建议业务逻辑简略,需要细化业务,增加业务开发,如未交费提醒等技术架构数据库:MySQL8.X后端技术:SpringBoot2.3.0,MyBatisPlus数据连接池:Druid前端技术:La......
  • springboot整合quartz达到动态配置定时任务的效果
    如题:首先贴上maven的配置<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId>......
  • SpringCloud之Config分布式配置文件中心
    分布式系统面临的配置问题:微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息......
  • 论项目中日志处理的正确操作(springboot案例)
    理论和日志的重要不需要重复,各位都明白,企业中甩锅 查询记录  必要的东西,直接贴上代码案例 maven<dependency><groupId>org.springframework.boot</groupI......
  • SpringBoot整合Swagger生成接口文档
    介绍:Swagger是一款RESTFUL接口的文档在线自动生成+功能测试功能软件。本文简单介绍了在项目中集成swagger的方法和一些常见问题。如果想深入分析项目源码,了解更多内容,见......
  • Spring的ioc介绍,配置文件和基本使用
    1.什么是spring,它能够做什么?  Spring是一个开源框架,它由RodJohnson创建。它是为了解决企业应用开发的复杂性而创建的。  Spring使用基本的JavaBean来完成以前只可......
  • 大数据框架hadoop安装以及简介
    介绍:Hadoop实现了一个​​分布式文件系统​​​(重点)(HadoopDistributedFileSystem),简称HDFS。HDFS有高​​容错性​​​的特点,并且设计用来部署在低廉的(low-cost)硬件上;......
  • springboot项目同时支持http和https访问
    首先使用https需要一个server.keystore,生成教程可以然后开始改动项目:配置文件中填入server.keystore的信息server.ssl.key-store=server.keystoreserver.ssl.key-alias=tomc......
  • SpringBoot Maven RepackageMojo 打包失败原因
    maven打包提示:org/springframework/boot/maven/RepackageMojohasbeencompiledbyamorerecentversionoftheJavaRuntime(classfileversion61.0),thisver......
  • 前端入门 HTTP协议 HTML简介
    目录前端和后端的概念前端前戏数据交互的协议HTTP协议1.四大特性1.基于请求响应2.基于TCP、IP作用与应用层之上的协议3.无状态4.无\短连接2.数据格式3.响应状态码(statu......