zoukankan      html  css  js  c++  java
  • 【Spring】AOP实现及原理

    5).Spring AOP编程:动态代理

    (1)引言(静态代理):
    现有代码的问题:
    ①事务代码耦合: 现有的事务控制的代码,耦合在了service方法中,一旦数据库访问技术发生变化,所
    有事务控制代码需要替换,导致service的代码被大量的修改
    ②事务控制的代码冗余: 大量相同的事务控制代码出现在了service方法中,出现冗余代码,不利于后期的升级和维护
    解决思路: 通过手动添加代理类,将事务控制代码放在代理类中
    代理类的核心规范 · 静态代理[重点]
    ① 先和目标类实现相同的接口
    ② 将额外功能(事务控制),放在代理类中
    ③ 调用目标对象的目标方法
    ④ 代替目标对象接受调用
    作用:将事务代码和service的核心功能代码解耦和
    缺点:每个目标类都要书写一个代理类,存在代码冗余
    (2)动态代理
    动态代理: 使用技术动态为目标类生成代理类
    代理类核心:
    ① 额外功能(事务控制等)
    ② 调用目标对象的方法
    ③ 和目标类拥有相同的接口
    Springaop技术的核心思想:
    ① 将额外功能的代码放在功能增强的对象中
    ② Spring AOP技术,将功能增强中的额外功能的代码,动态生成代理类,添加进去
    spring AOP的步骤:
    准备: 导入spring AOP依赖的jar(`asm.jar`  `cglib.jar`  `aspectj.awear.RELEASE.jar`)
    ①准备目标类(例如service)
    ②书写额外功能所在的 功能增强类
      public class 增强类 implements org.aopalliance.intercept.MethodInterceptor{
       	@Override
       	public Object invoke(MethodInvocation mi) throws Throwable {
       		//1. 开启事务
       		//2. 调用目标对象的功能。
       		Object o = mi.proceed();//调用真正的目标对象的方法
       		//3. 提交事务
       		return o;
       	}
      }
    ③通过aop技术,动态生成代理类 = 额外功能+目标对象
      核心:① 额外功能加入的位置: 切入点,是告诉spring将额外功能代码放在哪个方法的内部[告诉spring将额外功能加入哪个类的哪个方法中② 组装: 额外功能+类、方法(切入点)==代理类
    例子:
       	<!-- 1 管理目标对象UserServiceImpl -->
    	<bean id="us" class="com.jwnming.UserServiceImpl"></bean>
    	<!-- 2 管理增强类UserServiceImplZengqiang -->
    	<bean id="zengqiang" class="com.jwnming.UserServiceImplZengqiang"></bean>
    	<!-- 3 为us对象产生代理类,代理对象 :切入点、组装-->
    	<aop:config>
    		<!-- 切入点:明确目标类和目标方法 -->
    		<aop:pointcut id="pc" expression="execution(void com.jwnming.UserServiceImpl.regist())"></aop:pointcut>
    		<!-- 组装 -->
    		<aop:advisor pointcut-ref="pc" advice-ref="zengqiang"></aop:advisor>
    	</aop:config>		
    

    6).Spring AOP编程思想、MethodInterceptor接口详解

    (1)SpringAOP编程思想
    AOP:aspect orinted programing 面向切面编程,在不修改目标的代码的情况下,动态的为目标类的方法添加额外的功能代码
    本质:使用jdk技术,动态为目标类生成了代理类的,生成代理的对象,使用生成的代理对象替换了你的原始的目标对象
    (2)MethodInterceptor详解
    public class XxxAdvice implements MethodInterceptor{
    	@Override
    	public Object invoke(MethodInvocation mi) throws Throwable {    	//mi: 代表目标对象的方法
            Object o = mi.proceed();//调用目标对象的目标方法
    		return o;
    	}
    }
    ① 获得目标对象的方法:mi.getMethod();	//Method 类型的目标方法
    ② 目标对象:mi.getThis();			//获得目标对象
    ③ 获得代理的目标方法的调用时,实际传入的参数:mi.getArguments();	//数组,实际传入的参数
    ④ 调用目标对象的目标方法:Object o = mi.proceed();	//us.regist()     ps.add()
    	注:① 调用目标对象的方法 ② 返回值代表实际被代理的方法的返回值
    

    7).Spring的<aop:pointcut>标签几种切入点表达式

    切入点表达式详解
    pointcut切入点: 告诉spring功能增强的目标类的目标方法
    标签:<aop:pointcut  id=""  expression="切入点表达式"></aop:pointcut>
    (1)execution
    特点: 精确到方法声明的
    ① 精确点指定包指定类指定方法。
    execution(返回值 包名.子包.孙子包.类.方法名(参数1类型,参数2类型)); //参数类型之间用逗号隔开
    ② 精确到指定包下的指定类的执行方法,参数任意:
    execution(返回值 包名.子包.孙子包.类.方法名(..));
    ③ 精确到指定包的指定类,方法名任意,参数类型任意
    execution(返回值 包名.子包.孙子包.类.*(..));
    ④ 精确指定包下的任意类,任意方法,任意参数类型
    execution(返回值 包名.子包.孙子包.*.*(..));
    ⑤ 精确到指定包下的类,及其子包下的所有类的任意方法,任意参数,任意返回值类型
    execution(* p1.p2.p3..*.*(..));
    (2)within
    语法: expression="within(表达式语法)"
    特点: 表达式的写法,只精确到类
    ① 指定包下的类:				within(包名.类名);
    ② 指定包及其子包下的所有类:	within(p1.p2.p3..*);
    (3)@annotation
    语法: expression="@annotation(注解全类名)"
    特点: 凡是添加指定注解的方法,都会被功能增强
    使用步骤:
    ① 定义注解:public @interface HeheAdvice { }   //定义:添加了HeheAdvice注解的方法,都会被功能增强
    ② 使用注解:给需要功能增强的方法添加注解,例a1方法
    public class AServiceImpl{
    	@HeheAdvice
    	public void a1(){}
    }
    ③ 通过切入点,指定:添加@HeheAdvice的方法,进行功能增强
    	<aop:pointcut  id=""  expression="@annotation(注解名的全类名)"></aop:pointcut>
    
  • 相关阅读:
    产品小细节中的大体验
    产品经理的四点思考:不该简单满足用户需求
    产品经理的十大顶级错误
    SQL Server数据库大型应用解决方案总结
    java中public static void main(String[] args)中String[] args代表什么意思?
    异常处理1
    java中的String
    华为2013年西安java机试题目:如何过滤掉数组中的非法字符。
    2用java代码实现冒泡排序算法(转载)
    1用java实现冒泡排序算法以及解决的几个小问题。
  • 原文地址:https://www.cnblogs.com/jwnming/p/13635098.html
Copyright © 2011-2022 走看看