spring.net 学习笔记之 AOP

简介:
通常我们对于异常的处理方式都是大同小异的,要么直接捕获并处理,要么让它抛向上一层,要么就是记录到日志里,或者发邮件提供管理员,但这样下来一个项目中便会到处充斥着 try/catch ,并且 catch 中的代码基本类似,于是我们闻到的其中难闻的坏味道。

         本文将介绍如何通过  Spring . Net  的 AOP 特性实现异常的统一处理,如果我们需要在异常发生时做一些操作的话我们就必须实现  Spring .Aop.IThrowsAdvice,该接口没有任何实现方法,是一个空接口,它仅仅做为一个标记接口而存在,但实现了 IThrowsAdvice 接口的类必须定义至少一个 AfterThrowing 方法,方法的签名如下:

         AfterThrowing([MethodInfo method, Object[] args, Object target], Exception subclass);

         其中中括号括起来的前三个参数是可选的,返回值可以是任意数据类型。Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor 类实现对实现了 Spring.Aop.IThrowsAdvice 派生类中的方法依赖注入,其中的 ThrowsAdviceInterceptor() 方法检查 Spring.Aop.IThrowsAdvice 的派生类是否定义了至少一个异常处理方法,如果没有则抛出 ArgumentException 异常,MapAllExceptionHandlingMethods() 方法则在定义好的重载方法中查找出异常类型与最后一个参数所定义的类型中最接近的方法,而且我们不应该在其中实现了两个相同异常类型的方法,即使他们的参数数目不同,否则也将抛出 ArgumentException 异常。

         [下面引用自《Spring 技术手册》第4章 P94 页中的一段话]
         注意到当异常发生时, Throw Advice 的任务只是执行对应的方法,您并不能在 Throw Advice 中将异常处理掉,在 Throw Advice 执行完毕后,原告的异常仍将传播至应用程序之中, Throw Advice 并不介入应用程序的异常处理,异常处理仍旧是应用程序本身所要负责的,如果想要在 Throw Advice 处理时中止应用程序的处理流程,作法是抛出其它的异常。

         接下来看个 Throws Advice 的实际例子,首先定义 IHello 接口:

using  System;

namespace  TestThrowAdvice
{
    
public interface IHello
    
{
        
void Hello(string name);
    }

}

         接着定义一个 HelloSpeaker 类来实现 IHello 接口,并在 Hello() 方法中模拟程序发生错误时的异常抛出:

using  System;

namespace  TestThrowAdvice
{
    
public class HelloSpeaker : IHello
    
{
        
public void Hello(string name)
        
{
            Console.WriteLine(
"Hello, " + name);
            
//抱歉! 程序错误! 发生异常 XD
            throw new Exception("发生异常");
        }

    }

}




         如果您需要在应用程序抛出异常时,介入 Throw Advice 提供一些服务,例如记录一些异常信息,则可以实现 Spring.Aop.IThrowsAdvice 接口,在这个例子中我使用了 log4net 组件来实现日志的记录:

using  System;
using  Spring.Aop;
using  log4net;
using  log4net.Core;
using  System.Reflection;

[assembly: log4net.Config.XmlConfigurator(Watch 
=   true )]
namespace  TestThrowAdvice
{
    
public class SomeThrowAdvice : IThrowsAdvice
    
{
        
private ILog logger;

        
public SomeThrowAdvice()
        
{
            logger 
= LogManager.GetLogger(this.GetType());
        }


        
public void AfterThrowing(MethodInfo method, Object[] args, Object target, Exception exception)
        
{
            
// 记录异常
            logger.Info("记录异常", exception);
        }

    }

}

 
        接着在配置文件(我这里使用了独立配置文件)中写下以下的定义,让 Throw Advice 在异常发生时提供记录服务:

<? xml version="1.0" encoding="utf-8" ?>
< objects  xmlns ="http://www.springframework.net"  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  
         xsi:schemaLocation
="http://www.springframework.net 
         http://www.springframework.net/xsd/spring-objects.xsd"
>

  
< object  id ="SomeThrowAdvice"  type ="TestThrowAdvice.SomeThrowAdvice, TestThrowAdvice"   />
  
< object  id ="HelloSpeaker"  type ="TestThrowAdvice.HelloSpeaker, TestThrowAdvice"   />

  
< object  id ="HelloProxy"  type ="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop"   >
    
< property  name ="ProxyInterfaces" >
      
< list >
        
< value > TestThrowAdvice.IHello,TestThrowAdvice </ value >
      
</ list >
    
</ property >
    
< property  name ="Target" >
      
< ref  object ="HelloSpeaker"   />
    
</ property >
    
< property  name ="InterceptorNames" >
      
< list >
        
< value > SomeThrowAdvice </ value >
      
</ list >
    
</ property >
  
</ object >
  
</ objects >

 
        最后剩下我们的程序入口 Main() 函数了:

using  System;
using  Spring.Context;
using  Spring.Context.Support;

namespace  TestThrowAdvice
{
    
public class Program
    
{
        
static void Main(string[] args)
        
{
            log4net.Config.XmlConfigurator.Configure(); 
            IApplicationContext context 
= new XmlApplicationContext(@"../../SpringNet.xml");
            IHello helloProxy 
= (IHello)context.GetObject("HelloProxy");

            
try
            
{
                helloProxy.Hello(
"Justin");
            }

            
catch (Exception ex)
            
{
                
// 应用程序的异常处理
                Console.WriteLine(ex.Message);
            }

        }

    }

}

 
        程序执行结果输出:
         Hello, Justin
         发生异常...

         日志记录中的结果:
         2006-10-30 20:59:03,125 [4020] INFO  TestThrowAdvice.SomeThrowAdvice - 记录异常
         System.Exception: 发生异常...
            在 TestThrowAdvice.HelloSpeaker.Hello(String name) 位置 E:\..\..\SpringNetDemo\TestThrowAdvice\HelloSpeaker.cs:行号 14
            在 Spring.Objects.ObjectUtils.InvokeMethod(MethodInfo method, Object instance, Object[] arguments) 位置     c:\projects\daily\Spring.Net\src\Spring\Spring.Core\Objects\ObjectUtils.cs:行号 489
   在 Spring.Aop.Framework.ReflectiveMethodInvocation.InvokeJoinpoint() 。。。。。


本文转自BlogJava 新浪blog的博客,原文链接: spring.net 学习笔记之 AOP,如需转载请自行联系原博主。
相关文章
|
4月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
25天前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
2月前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
43 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
1月前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
30 1
|
26天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
33 0
|
3月前
|
设计模式 Java 测试技术
spring复习04,静态代理动态代理,AOP
这篇文章讲解了Java代理模式的相关知识,包括静态代理和动态代理(JDK动态代理和CGLIB),以及AOP(面向切面编程)的概念和在Spring框架中的应用。文章还提供了详细的示例代码,演示了如何使用Spring AOP进行方法增强和代理对象的创建。
spring复习04,静态代理动态代理,AOP
|
2月前
|
Java 编译器 Spring
Spring AOP 和 AspectJ 的区别
Spring AOP和AspectJ AOP都是面向切面编程(AOP)的实现,但它们在实现方式、灵活性、依赖性、性能和使用场景等方面存在显著区别。‌
89 2
|
2月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
137 9
|
2月前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
50 0
|
3月前
|
Java 数据库连接 数据库
Spring基础3——AOP,事务管理
AOP简介、入门案例、工作流程、切入点表达式、环绕通知、通知获取参数或返回值或异常、事务管理
Spring基础3——AOP,事务管理