• 学习Spring5必知必会(5)~Spring AOP




    一、学习 AOP 思想的准备工作:

    1、横切面关注点

    在开发中,为了给业务方法中增加日志记录,权限检查,事务控制等功能,此时我们需要在修改业务方法内添加这些零散的功能代码(横切面关注点)。

    • 这些零散存在于业务方法中的功能代码【例如:日志记录,权限检查,事务控制】,我们称之为横切面关注点

      横切面关注点不属于业务范围,应该 从业务代码中剥离出来.

    image



    2、AOP思想 (Aspect Oritention Programming):面向切面编程的思想

    • 切面:把一个个的横切关注点放到某个模块中去,称之为切面。

    • 那么每一个的切面都能影响业务的某一种功能, 切面的目的就是功能增强

      如日志切面就是一个横切关注点,应用中许多方法需要做日志记录的只需要插入日志的切面即可.

    image



    3、AOP 思想的原理:是动态代理



    4、了解 AOP 术语:

    • Joinpoint:连接点,被拦截到需要被增强的方法

    ​ where:去哪里做增强

    • Pointcut:切入点,哪些包中的哪些类中的哪些方法,可认为是连接点的集合。

    ​ where:去哪些地方做增强

    • Advice增强(通知),当拦截到 Joinpoint 之后,在方法执行的什么时机(when)做什么样(what)的增强

      ​ 根据时机分为:前置增强、后置增强、异常增强、最终增强、环绕增强

    • Aspect切面,Pointcut+Advice,

      ​ 去哪些地方+在什么时机+做什么增强


    • Target:目标对象,被代理的目标对象,委托对象。

    • Weaving:织入,把 Advice 加到 Target 上之后,创建出 Proxy 对象的过程。

    • Proxy:一个类被 AOP 织入增强后,产生的代理类 Advice(增强)执行时机,代理对象。



    5、Pointcot 语法 【找到具体的某个方法-哪个包.哪个类.哪个方法

    (1)AspectJ 切入点语法如下(表示在哪些包下的哪些类中的哪些方法上做切入增强):

    execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)

    即 ★execution(<修饰符>? <返回类型> <声明类型>? <方法名>(<参数>) <异常>)


    • 例子:public static Class java.lang.Class.forName(String className)throws ClassNotFoundException

    (2)切入点表达式中的通配符(看具体的方法,先从方法名位置开始看):

    ​ *:匹配任何部分,但是只能表示一个单词。

    ​ ..:可用于全限定名中和方法参数中,分别表示子包和 0 到 N 个参数




    二、AOP 开发:

    1、依赖:

    • spring-aop.jar
    • com.springsource.org.aopalliance.jar [spring5的spring-aop.jar已经包含]
    • com.springsource.org.aspectj.weaver.jar



    2、配置:

    (1)引入AOP的约束(在beans的基础进行修改即可)

    • 当然也可以使用插件sts,打开xml文件方式选择 Spring Config Editor

    image


    (2)配置AOP:

    	<!-- AOP 配置:在什么地点、什么时机、做什么 -->
    	<!-- 1、what【what(人物)】:做什么增强(关联what) -->
    	<bean id="transactionManager" class="com.shan.tx.TransactionManager"/>
    	
    	<aop:config proxy-target-class="false"> <!-- 属性proxy-target-class配置是否使用真实对象  -->
    		<!-- 配置AOP切面 -->  
    		<aop:aspect ref="transactionManager"> <!-- 关联what -->
    			<!-- 2、where【where+what(地点+人物)】:在哪些包中的哪些类中的哪些方法上做增强 -->
    			<aop:pointcut id="txPoint" expression="execution(* com.shan.service..*Service*.*(..))"/>
    			
    			<!-- 3、when【when+where+what(时间+地点+人物)】:在方法执行的什么时机(在哪里where-关联pointcut)做增强 -->
    			<aop:before method="open" pointcut-ref="txPoint"/>
    			<aop:after-returning method="commit" pointcut-ref="txPoint"/>
    			<aop:after-throwing method="rollback" pointcut-ref="txPoint"/>
    			<aop:after method="close" pointcut-ref="txPoint"/>
    			<aop:around method="aroundMethod" pointcut-ref="txPoint"/>	
    		</aop:aspect>
    	</aop:config>
    




    三、AOP 各种增强

    1、增强的分类:

    ■ 根据被增强的方法的执行时机分为:前置增强、后置增强、异常增强、最终增强、环绕增强

    • 前置增强:权限控制、日志记录等 [被增强的方法执行之前]
    • 后置增强:提交事务、统计分析数据结果等 [被增强的方法正常执行之后(中途没有异常)]
    • 最终增强:回滚事务、记录日志异常信息等 [被增强的方法出现异常]
    • 最终增强:释放资源等 [finally最后操作]
    • 环绕增强:缓存、性能日志、权限、事务管理等 [可以自定义在被增强方法的什么时机执行(返回一个Object,参数processdingJoinpoint)]

    image



    2、增强细节:

    (1)获取异常的信息:

    image

    public void rollback(Throwable ex) {
    	System.out.println("回滚事务~,异常信息:" +ex.getMessage());
    }
    

    (2)获取被增强方法的信息【获取被增强方法的信息,并且可以传递给增强方法】:

    • Spring AOP:Joinpoint类 连接点,访问被增强方法的真实对象,代理对象,方法参数等
    • 可以作为前置、后置、异常、最终增强方法的参数,第一个参数
    //可以作为前置、后置、异常、最终增强方法的参数,**`第一个参数`**	
    public void open(JoinPoint jp) {
    	System.out.println("开启事务~");
    	System.out.println("代理对象:" +jp.getThis().getClass());
    	System.out.println("目标对象:" +jp.getTarget().getClass());
    	System.out.println("被增强方法的参数:" +Arrays.toString(jp.getArgs()));
    	System.out.println("连接点方法的签名:" +jp.getSignature());
    	System.out.println("当前连接点的类型:" +jp.getKind());
    }
    

    (3) 环绕增强方法调用真实对象的方法【参数processdingJoinpoint】:

    • 参数processdingJoinpoint:是JointPoin 的子类,只能用于环绕增强,作为第一个参数

      还可以调用真实对象中被增强的方法。

    //调用真实对象的方法 ret = pjp.proceed();
    public Object aroundMethod(ProceedingJoinPoint pjp) {
    		Object ret = null;
    		System.out.println("开启事务~");
    		try {
    			ret = pjp.proceed();//调用真实对象的方法
    			System.out.println("调用真实对象的方法...~");
    			System.out.println("提交事务~");
    		} catch (Throwable e) {
    			System.out.println("回滚事务~,错误信息:" + e.getMessage());
    		}finally {
    			System.out.println("关闭资源~");
    		}
    		return ret;
    	}
    




    四、使用注解配置AOP

    AOP 注解:

    (1)在配置文件中添加注解的解析器的配置【第三方程序(赋予注解的特殊功能)】:

    • 使用cglib注解:配置属性proxy-target-class="true"
       <!-- AOP注解的解析器 -->
       <aop:aspectj-autoproxy/>
    

    (2)使用注解@Aspect配置一个AOP切面

    • @Pointcut (配置where)
    • @Before、@AfterReturning、@AfterThrowing、@After、@Around(配置when
    @Component@Aspect //配置一个AOP切面
    public class TransactionManager {
    	
    	//where
    	//xml:<aop:pointcut id="txPoint" expression="execution(* com.shan.service..*Service*.*(..))"/>
    	@Pointcut("execution(* com.shan.service..*Service*.*(..))")
    	public void txPoint() {
    		
    	}
    	
    	//@Before("txPoint()")
    	public void open(JoinPoint jp) {
    		System.out.println("开启事务~");
    	}
    
    	//@AfterReturning("txPoint()")
    	public void commit() {
    		System.out.println("提交事务~");
    	}
    	//@AfterThrowing(value="txPoint()", throwing="ex")
    	public void rollback(Throwable ex) {
    		System.out.println("回滚事务~,异常信息:" +ex.getMessage());
    	}
    	//@After("txPoint()")
    	public void close() {
    		System.out.println("关闭资源~");
    	}
    	
    	@Around("txPoint()")
    	public Object aroundMethod(ProceedingJoinPoint pjp) {
    		Object ret = null;
    		System.out.println("开启事务~");
    		try {
    			ret = pjp.proceed();//调用真实对象的方法
    			System.out.println("调用真实对象的方法...~");
    			System.out.println("提交事务~");
    		} catch (Throwable e) {
    			System.out.println("回滚事务~,错误信息:" + e.getMessage());
    		}finally {
    			System.out.println("关闭资源~");
    		}
    		return ret;
    	}
    }
    
  • 相关阅读:
    Lua 学习之基础篇七<Lua Module,Package介绍>
    Lua 学习之基础篇六<Lua IO 库>
    Lua 学习之基础篇五<Lua OS 库>
    Lua 学习之基础篇四<Lua table(表)>
    Lua 学习之基础篇三<Lua 字符串操作>
    时空穿梭
    【集训队作业】line
    动态几何问题
    博弈论与概率统计
    wombats
  • 原文地址:https://www.cnblogs.com/shan333/p/15953312.html
Copyright © 2020-2023  润新知