zoukankan      html  css  js  c++  java
  • 循序渐进之Spring AOP(3)

    上一篇介绍了几种Advice(增强),并通过代码演示了生成代理的方式,下面来看通过配置文件配置方式把Advice织入目标类。

    注意,配置文件方式仍然不是spring AOP的最好方式,学习配置方式也是为了循序渐进的掌握内核技术。

    接口SmartCar

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public interface SmartCar {  
    2.     void lock(String userName);  
    3. }  

    实现类MyCar

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public class MyCar implements SmartCar {  
    2.     @Override  
    3.     public void lock(String userName) {  
    4.         System.out.println(userName + "锁车");  
    5.     }  
    6. }  

    定义了两个增强,一个在锁车方法前执行,提示检查窗户是否关闭,一个在锁车方法后执行,"哔哔"声提示锁车成功

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public class BeforeAdviceDemo implements MethodBeforeAdvice {  
    2.     @Override  
    3.     public void before(Method method, Object[] args, Object obj)  
    4.             throws Throwable {  
    5.         System.out.println("请检查窗户是否关好");  
    6.     }  
    7. }  
    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public class AfterAdviceDemo implements AfterReturningAdvice {  
    2.     @Override  
    3.     public void afterReturning(Object returnObj, Method method, Object[] args,  
    4.             Object obj) throws Throwable {  
    5.         System.out.println("哔哔");  
    6.     }  
    7. }  

    applicationContext.xml: 用配置文件来声明代理

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. <beans xmlns="http://www.springframework.org/schema/beans"  
    2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
    3.     xmlns:context="http://www.springframework.org/schema/context"  
    4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
    5.   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    6.   http://www.springframework.org/schema/context  
    7.   http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
    8.   
    9.     <bean id="beforeAdvice" class="demo.aop.BeforeAdviceDemo" />  
    10.     <bean id="afterAdvice" class="demo.aop.AfterAdviceDemo" />  
    11.     <bean id="target" class="demo.aop.MyCar" />  
    12.       
    13.     <bean id="myCar" class="org.springframework.aop.framework.ProxyFactoryBean"  
    14.         p:target-ref="target"  
    15.         p:proxyTargetClass="true">  
    16.         <property name="interceptorNames">  
    17.             <list>  
    18.                 <idref local="beforeAdvice" />  
    19.                 <idref local="afterAdvice" />  
    20.             </list>  
    21.         </property>  
    22.     </bean>  
    23. </beans>  

    测试代码

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public static void main(String[] args) {  
    2.     ApplicationContext context = new ClassPathXmlApplicationContext("demo/aop/applicationContext.xml");  
    3.     SmartCar myCar = (SmartCar)context.getBean("myCar");  
    4.     myCar.lock("Tom");  
    5. }  

    执行结果

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. 请检查窗户是否关好  
    2. Tom锁车  
    3. 哔哔  

    配置文件中首先声明了3个bean,分别是增强的目标类和两个增强,没有特别的配置内容。重点是ProxyFactoryBean的配置,来看看它可配置的属性和用法。

    target 目标对象,ref另一个bean
    proxyTargetClass 是否对类进行代理(而不是对接口),true或false,设置为true时,使用CGLib代理技术
    interceptorNames 织入目标对象的Advice(实现了Advisor或者MethodInterceptor接口的bean)
    proxyInterfaces 代理所要实现的接口,如果指定了proxyTargetClass=true,此属性会被忽略
    optimize 设置为true时,强制使用CGLib代理技术

    下面再分别增加一个环绕增强和一个异常抛出增强。

    先修改MyCar类,使它能够抛出异常,粗心的约翰会忘记锁车而抛出一个异常

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public class MyCar implements SmartCar {  
    2.     @Override  
    3.     public void lock(String userName) {  
    4.         if(userName.equals("Careless John")) {  
    5.             throw new RuntimeException(userName + "忘记锁车");  
    6.         } else {  
    7.             System.out.println(userName + "锁车");  
    8.         }  
    9.     }  
    10. }  

    环绕增强类

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public class AroundAdviceDemo implements MethodInterceptor {  
    2.     @Override  
    3.     public Object invoke(MethodInvocation invocation) throws Throwable {  
    4.         Object[] args = invocation.getArguments();  
    5.         String name = (String)args[0];  
    6.         System.out.print("Hey, " + name);  
    7.         Object obj = invocation.proceed(); //调用目标方法  
    8.         System.out.println("Goodbye! " + name);  
    9.         return obj;  
    10.     }  
    11. }  

    异常抛出增强

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public class ThrowsAdviceDemo implements ThrowsAdvice {  
    2.     public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {  
    3.         System.out.println("捕获异常:" + ex.getMessage());  
    4.         System.out.println("(报警)滴滴滴滴滴滴滴滴滴滴滴滴");  
    5.     }  
    6. }  

    applicationContext.xml

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. <beans xmlns="http://www.springframework.org/schema/beans"  
    2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
    3.     xmlns:context="http://www.springframework.org/schema/context"  
    4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
    5.   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    6.   http://www.springframework.org/schema/context  
    7.   http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
    8.   
    9.     <bean id="beforeAdvice" class="demo.aop.BeforeAdviceDemo" />  
    10.     <bean id="afterAdvice" class="demo.aop.AfterAdviceDemo" />  
    11.     <bean id="aroundAdvice" class="demo.aop.AroundAdviceDemo" />  
    12.     <bean id="throwsAdvice" class="demo.aop.ThrowsAdviceDemo" />  
    13.     <bean id="target" class="demo.aop.MyCar" />  
    14.       
    15.     <bean id="myCar" class="org.springframework.aop.framework.ProxyFactoryBean"  
    16.         p:target-ref="target"  
    17.         p:proxyTargetClass="true">  
    18.         <property name="interceptorNames">  
    19.             <list>  
    20.                 <idref local="aroundAdvice" />  
    21.                 <idref local="throwsAdvice" />  
    22.                 <idref local="beforeAdvice" />  
    23.                 <idref local="afterAdvice" />  
    24.             </list>  
    25.         </property>  
    26.     </bean>  
    27. </beans>  

    测试代码

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public static void main(String[] args) {  
    2.     ApplicationContext context = new ClassPathXmlApplicationContext("demo/aop/applicationContext.xml");  
    3.     SmartCar myCar = (SmartCar)context.getBean("myCar");  
    4.     myCar.lock("Tom");  
    5.     System.out.println("-------------------------");  
    6.     myCar.lock("Careless John");  
    7. }  

    运行结果

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. Hey, Tom请检查窗户是否关好  
    2. Tom锁车  
    3. 哔哔  
    4. Goodbye! Tom  
    5. -------------------------  
    6. Hey, Careless John请检查窗户是否关好  
    7. 捕获异常:Careless John忘记锁车  
    8. (报警)滴滴滴滴滴滴滴滴滴滴滴滴  

    除了上面的四种增强,还有一种特殊的引介增强(Introduction),在下一篇中单独介绍

  • 相关阅读:
    打印九九乘法三角形的各种思路
    7-14 倒数第N个字符串
    7-13 求阶乘序列前N项和
    7-12统计学生成绩
    Discrete Mathematics and Its Applications | 1 CHAPTER The Foundations: Logic and Proofs | 1.3 Propositional Equivalences
    Discrete Mathematics and Its Applications | 1 CHAPTER The Foundations: Logic and Proofs | 1.2 Applications of Propositional Logic
    Discrete Mathematics and Its Applications | 1 CHAPTER The Foundations: Logic and Proofs | 1.1 Propositional Logic
    [Mac Terminal] ___切换到其他路径和目录
    [Mac Terminal] ___MAC终端清屏快捷键
    部署flask到linux服务器
  • 原文地址:https://www.cnblogs.com/sa-dan/p/6837190.html
Copyright © 2011-2022 走看看