SpringAOP
咱们为什么要应用AOP(面向切面编程)?当咱们在事实中实现理论的我的项目时,咱们总是须要在一个“动作”进行前,进行中,或进行后进行一些操作,比方当咱们在运行程序时,咱们想要进行日志保留,或者在每一个办法调用后输入一句话,这就示意咱们每一次进行一个“动作”都须要进行同样的操作,这就导致程序员会进行大量的、无用的重复性动作,面对这种状况,AOP应运而生。
AOP概述
AOP,即Aspect Oriented Rrogramming的缩写,意为:面向切面编程,通过预编译形式和运行期间动静代理实现程序性能对立保护的一种技术。AOP能够对业务漏极的各个局部进行隔离,从而使得业务逻辑之间得耦合性升高,进步程序得可重用性,同时进步了开发得效率。
AOP和OOP是两种不同的设计思维。OOP(面向对象编程)针对业务处理过程得实体及其属性和行为进行形象封装,取得清晰高效得逻辑单元划分。AOP则是针对业务处理过程中得切面进行提取,是面对业务处理过程中的某个步骤或阶段,取得逻辑过程中各局部之间低耦合性得隔离成果。
面向切面编程的益处就是:缩小反复,专一业务。它是面向对象编程的一种补充。
集体整顿了一些材料,有须要的敌人能够间接点击支付。
Java基础知识大全
22本Java架构师外围书籍
从0到1Java学习路线和材料
1000+道2021年最新面试题
外围原理及应用案例
原理:应用动静代理的形式在执行办法前后或出现异常时退出相干的逻辑。
应用:
事务处理:开启事务,敞开事务,出现异常回滚事务.....
权限判断:执行办法前,判断是否具备权限;
日志解决;
......
事务处理:开启事务,敞开事务,出现异常回滚事务.....
权限判断:执行办法前,判断是否具备权限;
日志解决;
......
AOP的基本概念(Spring的专业术语)
0.加强:向各个程序外部注入一些逻辑代码从而加强原有程序的性能。
1.连接点(JoinPoint):类中能够被加强的办法,这个办法就就被称为连接点,切记连接点并不是肯定会被加强。
2.切入点(Pointcut):类中理论被加强的办法。
3.告诉(Advice):指一个切面在特定的连接点要做的事件,简略来说就是“加强”。能够分为办法执行前告诉,办法执行后告诉,盘绕告诉等等。
4.切面(Aspect):把告诉增加到切入点的过程就叫切面。
5.指标(Target):代理的指标对象,即要加强的办法所在的类。
6.代理(Proxy):向指标对象利用告诉之后创立的代理对象。
SpringAOP实现
很多的框架都对AOP这种编程思维进行了实现。Spring只是其中的一种,能够实现面向切面编程。AspectJ也是一个面向切面的框架,并且实现形式更为简捷,更为不便,并且反对注解式开发。所以,Spring又将AspectJ对于AOP的实现引入到本人的框架之中。
Spring中应用AOP开发时,通常应用AspectJ的实现形式。其中罕用的告诉有五种类型:
- 前置告诉:办法执行前执行;
- 后置告诉:办法执行后执行;
- 盘绕告诉:前后都执行;
- 异样告诉:出异样时告诉;
- 最终告诉:如return后执行。
SpringAOP的应用
导入实现AOP的AspectJ的jar
<!--Spring实现AOP是依附Aspects框架实现-->
<!--Aspects相干jar-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
基于AspectJ的xml配置实现
所有的配置都在spring.xml文件中进行。
1.创立一个加强性能的类。
import org.aspectj.lang.ProceedingJoinPoint;
//告诉(Advice):在连接点要做的事件
public class Aop {
public void doLog() {
System.out.println("=====保留日志=====");
}
public void commit() {
System.out.println("=====提交事务=====");
}
public void around(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("======办法前告诉======");
try {
proceedingJoinPoint.proceed();//调用本人的办法
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("======办法后告诉======");
}
public void throwable(Throwable throwable) {
System.out.println("======出异样了======");
System.out.println(throwable.getMessage());
}
}
2.将装有加强性能的类交给交由spring治理
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--把装有告诉(Advice)的类交给Spring治理-->
<bean id="aop" class="com.cwd.spring4pro.demo1.aop.Aop"></bean>
<!--在这里进行织入,即切面(Aspect):将告诉增加到切入点-->
</beans>
3.配置切面(Aspect)
先筹备一个被加强的类,即指标(Target)
import org.springframework.stereotype.Component;
//指标(Target):代理的指标对象,即要加强的类
@Component(value = "target")
public class Target {
/*
连接点(Joinpoint),能够被加强的办法
切入点(pointcut),理论被加强的办法,被加强了
*/
public void pointCut() {
System.out.println("这是一个保留的操作!!!");
return;
}
}
将告诉增加到切入点。
<!--织入-->
<aop:config>
<!--
配置切入点
execution表达式 前*示意返回值 saveUser(..)示意要加强的办法 ..示意参数
-->
<aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
<!--配置告诉 ref中援用的是告诉类的id-->
<aop:aspect ref="aop">
<!--前置告诉-->
<aop:before method="doLog" pointcut-ref="pointCut"/>
</aop:aspect>
</aop:config>
五种告诉类型配置
1.前置告诉
<!--织入-->
<aop:config>
<aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
<aop:aspect ref="aop">
<!--前置告诉-->
<aop:before method="doLog" pointcut-ref="pointCut"/>
</aop:aspect>
</aop:config>
2.后置告诉
<!--织入-->
<aop:config>
<aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
<aop:aspect ref="aop">
<!--后置告诉-->
<aop:after method="commit" pointcut-ref="pointCut"/>
</aop:aspect>
</aop:config>
3.盘绕告诉
<!--织入-->
<aop:config>
<aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
<aop:aspect ref="aop">
<!--盘绕告诉-->
<aop:around method="around" pointcut-ref="pointCut"/>
</aop:aspect>
</aop:config>
4.异样告诉
public void pointCut() {
System.out.println("这是一个保留的操作!!!");
int a = 10 / 0;
return;
}
<!--织入-->
<aop:config>
<aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
<aop:aspect ref="aop">
<!--异样告诉-->
<aop:after-throwing method="throwable" pointcut-ref="pointCut" throwing="throwable"/>
</aop:aspect>
</aop:config>
5.最终告诉
<!--织入-->
<aop:config>
<aop:pointcut id="pointCut" expression="execution(* com.cwd.spring4pro.demo.Target.pointCut(..))"/>
<aop:aspect ref="aop">
<!--最终告诉-->
<aop:after-returning method="commit" pointcut-ref="pointCut"/>
</aop:aspect>
</aop:config>
最终告诉个别在return之后执行。
注解实现
开启aop注解扫描
<!--开启注解标签-->
<aop:aspectj-autoproxy/>
在告诉类中进行配置,如下所示:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component//将这个类交给Spring治理
@Aspect//标注这个类时装有告诉的类
public class Aop {
@Before("execution(* com.cwd.spring4pro.demo.Target.pointCut(..))")
public void doLog() {
System.out.println("=====保留日志=====");
}
@After("execution(* com.cwd.spring4pro.demo.Target.pointCut(..))")
public void commit() {
System.out.println("=====提交事务=====");
}
public void around(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("======办法前告诉======");
try {
proceedingJoinPoint.proceed();//调用本人的办法
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("======办法后告诉======");
}
@AfterThrowing(value = "execution(* com.cwd.spring4pro.demo.Target.pointCut(..))",throwing = "throwable")
public void throwable(Throwable throwable) {
System.out.println("======出异样了======");
System.out.println(throwable.getMessage());
}
@AfterReturning("execution(* com.cwd.spring4pro.demo.Target.pointCut(..))")
public void returnAfter() {
System.out.println("======return后=====");
}
}
最初
都看到这里了,感觉文章对你有帮忙的话记得点个赞,感激反对!
发表回复