Spring核心2----AOP面向切面编程、动态代理、aspectj实现

一、AOP思想及相关术语

1、AOP(Aspect Orient Programing)---面向切面编程

(1) 其底层实现就是动态代理

    AOP是动态代理技术的一种规范化,让实现灵活的动态代理用一种统一的方式实现,避免矛盾

(2)切面(Aspect)

          给目标类增加的功能就是切面,如给原程序添加的日志和事务功能就是切面

 (3)   切面特点:一般都是非业务功能,可独立使用

2、AOP的作用(动态代理的作用)

      (1)在不改变原来业务代码的基础上,额外增加业务功能

     (2)减少代码的重复

     (3)专注业务逻辑代码

     (4)解耦合,让业务功能和日志、事务等非业务功能分离

3、常见几种编程思想

   OOP:面向对象编程

            以对象为基础来构建类,并表示类的属性,类之间关系

            首先分析功能,功能中用到那些对象,以对象构建类,类中有那些属性,类与类之间是什么关系,继承  实现等

    OIP:面向接口编程

            解耦合

   AOP:面向切面编程的理解

           (1)需要在分析项目功能时,找出切面,即哪些功能是非业务的,可独立使用的附加功能

           (2)合理安排切面的执行时间,在目标方法前还是后

           (3)合理的安全切面执行的位置,在哪个类,哪个方法增加功能

            以切面为核心,分析出切面,合理安排切面的执行时间和位置

4、AOP术语:

 (1)Aspect切面,表示增强的功能,即一堆代码完成某个功能(非业务功能)

                    常用切面:日志,事务,统计信息,参数检查,权限验证

 (2)JoinPoint:连接点,连接业务方法和切面的位置,即某个类中要增强的业务方法,

                            如 someService接口实现类中的doSome和doOther方法

 (3)Pointcut切入点,指多个连接点的集合, 多个方法都要增强这个功能(切入点表达式)

 (4)目标对象:给哪个类的方法增加功能,这个类就是目标对象

(5)Advice通知,表示切面功能执行的时间,即执行顺序,在目标方法的哪里执行

5、切面三要素

   (1)切面:切面的功能代码,切面是具体干什么的(aspect 切面一般封装在util包下)

   (2)切入点:切面的执行位置,哪些方法需要增强(Pointcut 切入点)

   (3)通知:切面的执行时间,在方法前执行还是方法后执行(Advice 通知)

二、动态代理

  1、动态代理可以是jdk和cglib两种方式

     AOP将动态代理的实现步骤、方式都定义好了,让开发人员用一种统一的方式实现动态代理

  2、jdk动态代理----实现接口

     (1)功能类---实现接口InvocationHandler

     (2)类中invoke方法-----写功能代码

      (3)proxy类---用来创建代理对象

      代码详见动态代理部分:待补充

 3、cglib动态代理---继承

  (1)使用FastClass机制为代理类和被代理类各生成一个类

          生成的这个类会为各自代理类或被代理类的方法生成一个index

  (2)方法的index被作为参数直接定位到要调用的方法

   (3)第三方工具库实现代理对象的创建,要求目标类可继承

具体见:详述 动态代理---JDK动态代理和cglib动态代理_@snow'的博客-CSDN博客_cglib动态代理和jdk代理

三、aspectj框架实现

1、aspectj框架介绍 

     一个开源的 专门做AOP的框架(来自eclipse)

     spring框架中集成了aspectJ框架,通过spring就能使用aspectJ功能

2、 aspectJ框架实现AOP的两种方式

       <1>使用xml配置文件:主要用于配置全局事务

        <2>使用注解:项目中实现AOP功能一般使用注解

3、aspectJ的五个注解---切面的执行时间----Advice 通知(增强)

  (1)   @Before  前置通知

  •       方法之前执行;
  •        没有返回值

   (2)@AfterReturing  后置通知

  •      原方法之后执行;
  •      要传参数,有返回值

   (3) @Around  环绕通知

  •    可前可后,主要依据实现部分增强方法相对于被增强方法的位置
  •    必须有返回值,一般用于事务的处理

     (4)@AfterThrowing 异常通知 

  •     方法没有返回值
  •     方法可以没有参数,如果有就是JoinPoint
  •    调用的方法有异常,该通知注解的方法才会执行,并抛出信息,没有异常时不执行

     (5)@After  最终通知

  •     总会执行的,功能同异常中的finally
  •     即使有异常也会执行

4、切面的执行位置----切入点表达式:

(1)一般形式

@before(value="execution(访问权限 方法返回值 方法声明(参数) 异常类型)")

 其中访问权限和异常类型可省略  , 必有的是方法返回值和方法名及对应参数

(2)表达式中的通配符:

          

(3)例子

  

5、实现步骤

(1)在Maven工程xml文件 pom.xml中加入依赖

  •   spring依赖
  •   aspectj依赖
  • Junit单元测试依赖

(2)创建目标类

        一般为service接口及其实现类

(3)创建切面类 --- java普通类,用来实现增加的功能

      <1>在类上加@Aspect

      <2>在类中定义方法实现功能

               指定切面执行时间---在方法上加aspectj的通知注解,@before @after

               指定切面执行位置---切入点表达式 execution()

    (4)创建spring的配置文件 声明对象-----把对象交给容器统一管理(xml或注解方式)

      <1>声明目标对象

     <2>声明切面对象

     <3>声明aspectj框架中的 自动代理生成器  用来完成代理对象的自动创建功能

   (5)测试中通过动态代理对象调用原方法,代理对象实际调用增强后的方法,完成功能添加实现

 6、代码实现

  • 目标类
//目标类接口
public interface SomeService{
   pubblic void doSome(String name,Integer age);
}

//接口类实现类
public class SomeServiceImpl inplements SomeService{
   
   pubblic void doSome(String name,Integer age){
    System,.out.println("这是目标方法");
  }
}
  •  切面类
@Aspect
public class MyAspect{
   @Before(value=
           "execution(public void com.sqf.service.SomeServiceImpl.doSome(String,Integer))")
  public void myBefore(){
     //切面要执行的代码
   System.out.println("前置通知:在目标方法之前输出执行时间:"+new Date());
  }
}
  • spring配置文件中声明目标对象、切面对象和自动代理生成器
<bean id="someService" class="com.sqf.service.SomeServiceImpl">
<bean id="myAspect" class="com.sqf.service.myAspect">
<aop:aspectj-autoproxy>

[注]两种代理的使用情况:

   一般目标类是一个接口实现类(SomeServiceImpl )-------默认使用jdk动态代理

     若目标类非接口实现类,是普通类(Student)--------默认使用cglib动态代理

     若是接口实现类想要强制使用cglib-----<aop:aspectj-autoproxy proxy-target-class=true>

  • 测试:通过容器获取代理对象 
String config="applicationContext.xml";//spring配置文件名
Application ctx=ClassPathXmlApplicationContext("config");//创建容器对象
SomeService proxy=(SomeService)ctx.getBean("someService");//通过容器获取目标对象的代理对象
proxy.doSome('zs'.20);//代理对象执行的方方,实际是增强了功能----先输出时间,再输出"这是目标方法"

这是动态代理规范化的实现方法,一般动态代理实现详见动态代理----待补充

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值