1
  • 想要熟悉流程的时候,一定要多多打断点

  • jdkproxy的优点

    • 动态的产生代理对象,只需要一个拦截器就可以了

  • jdkproxy的缺点

    • 如果在invoke方法中做事务的判断, 是很复杂的事情

    • 程序员还需要对invoke方法进行修改,写拦截器

  • 新的事物是对老事物的改进及完善


AOP(针对的是大量的重复性的工作)

  • AOP的意义
    图片描述


  • AOP的各个概念
    图片描述


检验切入点表达式配置是否成功,可以查看一下代理对象是否正确


AOP的原理

1 启动spring容器
2 实例化PersonDao和Transaction
3 spring容器解析aop:config配置

  • 当spring容器解析到切入点表达式的时候,将切入点表达式中的解析出来

  • 将切入点表达式的类与spring容器中的类进行匹配

    • 成功,为该对象创建代理对象

    • 失败, 则报错

代理对象方法的形成 = 通知 + 目标方法

4 在客户端context.getbean()中, 有代理对象则返回代理对象。没有则返回原对象
5 在spring内部,需要判断目标类是否实现了接口

  • 如果实现了, 有jdkproxy来产生代理对象

  • 如果没有实现, 由cglibproxy来产生代理对象


aop xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
   <!-- 
             导入目标类
             导入切面
             进行aop的配置
    -->
   <bean id="personDao" class="com.itheima11.spring.aop.xml.transaction.PersonDaoImpl"></bean>
   <bean id="transaction" class="com.itheima11.spring.aop.xml.transaction.Transaction"></bean>
   
   <aop:config>
           <!-- 
               pointcut切入点表达式
                 符合切入点表达式的类要产生代理对象
                 expression就是切入点表达式
                 id 标示符
            -->
           <aop:pointcut 
               expression="execution(* com.itheima11.spring.aop.xml.transaction.PersonDaoImpl.*(..))" 
               id="perform"/>
           <!-- 
               ref属性指向切面
            -->
           <aop:aspect ref="transaction">
               <!-- 
                   前置通知
                      在目标方法执行之前
                -->
               <aop:before method="beginTransaction" pointcut-ref="perform"/>
               <!-- 
                   后置通知
                -->
               <aop:after-returning method="commit" pointcut-ref="perform"/>
           </aop:aspect>
   </aop:config>
</beans>
    

AOP各种通知

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
   <bean id="personDao" class="aop.xml.transaction.PersonDaoImpl"></bean>
   <bean id="transaction" class="aop.xml.transaction.Transaction"></bean>
    <aop:config>
        <aop:pointcut 
            expression="execution(* aop.xml.transaction.PersonDaoImpl.*(..))" 
            id="perform"/>
        <aop:aspect ref="transaction">
            <!-- 
                前置通知
                    1、在目标方法执行之前
                    2、前置通知中,方法有一个参数JoinPoint
             -->
            <!-- 
            <aop:before method="beginTransaction" pointcut-ref="perform"/>
             -->
            <!-- 
                后置通知
                   1、在目标方法执行之后
                   2、能够获取目标方法的返回值
                       returning="val"
                   3、如果目标方法产生异常,则后置通知不再执行
             -->
            <!-- 
            <aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>
             -->
            <!-- 
                异常通知
                          获取目标方法抛出的异常信息
                    throwing="ex"
             -->
            <aop:after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"/>
            <!-- 
                最终通知
             -->
            <aop:after method="finallyMethod" pointcut-ref="perform"/>
            <!-- 
                环绕通知
                      能够控制目标方法的执行
                      环绕通知可以有返回值,这个返回值就是代理对象的方法的返回值
                      前置通知和后置通知只能在目标方法执行之前和之后加代码,但是不能控制目标方法的执行
             -->
            <aop:around method="aroundMethod" pointcut-ref="perform"/>
        </aop:aspect>
    </aop:config>
</beans>

出现问题抛异常,在一处处理就可以了


SportCloud
157 声望9 粉丝

数据仓库


下一篇 »
AJAX