1. 程式人生 > >AOP系列(一)——ProxyFactoryObject 顯式建立AOP代理

AOP系列(一)——ProxyFactoryObject 顯式建立AOP代理

AOP概念

  Aspect Oriented Programming,面向切面程式設計,可以通過預編譯方式和執行期動態代理,實現在不修改原始碼的情況下給程式動態統一新增功能的一種技術。

前提


  • 瞭解Spring.NET IOC
  • 熟悉代理模式

  下面我們結合一個具體的例子來了解AOP。

基本情景

這裡寫圖片描述

User類

    /// <summary>
    /// 使用者實體,具有姓名和年齡兩個屬性
    /// </summary>
    public class User
    {
        public string Name { get
; set; } public int Age { get; set; } }

IUserService

    public interface IUserService
    {
        //獲得使用者資訊
        void GetUserInfo(User enUser);
    }

UserService

    public class UserService:IUserService
    {
        /// <summary>
        /// 獲得使用者的資訊
        /// </summary>
/// <param name="enUser">使用者實體</param> public void GetUserInfo(User enUser) { //輸出使用者的姓名和年齡 Console.WriteLine("姓名:"+enUser .Name+"年齡:"+enUser .Age ); } }

客戶端(控制檯應用程式)Program

  • “ new()”出具體的實現——這裡我們不採用此方式
    class Program
    {
static void Main(string[] args) { //例項化一個實體 User enUser = new User() { Name = "Danny", Age = 15 }; IUserService userService = new UserService(); userService.GetUserInfo(enUser); } }
  • 通過Spring IOC獲得具體實現(相當於工廠)
//引入Spring.Core.dll
using Spring.Context;
using Spring.Context.Support;

namespace WithoutAOP
{
    class Program
    {
        static void Main(string[] args)
        {
            //例項化一個實體
            User enUser = new User()
            {
                Name = "Danny",
                Age = 15
            };          

            //獲得Spring.IOC容器的上下文
            IApplicationContext context = ContextRegistry.GetContext();
            //根據配置檔案中的配置獲得業務實現類
            IUserService userService = (IUserService)context.GetObject("userService");
            //呼叫業務實現類的方法
            userService.GetUserInfo(enUser);
        }
    }
}

配置檔案

    <!--Spring配置-->
    <configSections>
        <sectionGroup name="spring">
            <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
            <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
        </sectionGroup>
    </configSections>
    <spring>
        <context>
            <resource uri="config://spring/objects"/>
        </context>
        <objects xmlns="http://www.springframework.net">
            <object id="userService" type="AOPExample.UserService,AOPExample"/>
        </objects>
    </spring>

  現在我們要為已有的業務邏輯增加日誌功能。接下來看看AOP如何來實現。
  在瞭解之前,我們先來了解AOP中的一些術語。

AOP術語

這裡寫圖片描述

  • 目標物件(Target),即我們要代理的物件(UserService),也就是我們要為此物件增加日誌功能。
  • 關注點(Concern):如日誌功能。日誌功能是系統級別的,不可能只在一個物件中增加日誌功能。
  • 通知(Advice):在Advice中寫日誌功能的具體實現。通知類實現不同的介面,如:Before,After……這些決定了日誌功能如何新增(切入)到業務邏輯中,是在業務邏輯執行前新增,還是執行後新增。

AOP實現思路

  • 寫具體的通知類Advice(實現日誌功能)
  • 在配置檔案中進行配置

    • 配置生成代理類的方式
    • 配置目標物件(可以直接配置具體的目標物件,也可以通過名稱或正則表示式,程式執行後會在容器中尋找到符合條件的物件作為目標物件)

    • 配置通知類

ProxyFactoryObject 顯式建立AOP代理

Advice通知類

//引入System.Aop.dll;
using Spring.Aop;       //AOP
using System.Reflection;//反射
namespace AOPExample
{
    /// <summary>
    /// Advice通知類:實現日誌功能
    /// </summary>
    public class LogBeforeAdvice:IMethodBeforeAdvice
    {
        /// <summary>
        /// 實現介面IMethodBeforeAdvice中的Before方法,在目標方法執行前執行Before()
        /// </summary>
        /// <param name="method">攔截的方法</param>
        /// <param name="args">方法的引數</param>
        /// <param name="target">攔截的物件</param>
        public void Before(MethodInfo method, object[] args, object target)
        {
            Console.WriteLine("攔截的方法名—>" + method.Name);
            Console.WriteLine("目標物件—>" + target);
            Console.WriteLine("引數—>");

            //如果引數不為空,遍歷所有引數並輸出
            if (args != null)
            {
                foreach (object arg in args)
                {
                    Console.WriteLine("\t: " + arg);
                }
            }  
        }
    }
}

配置檔案

<?xml version="1.0"?>
<configuration>
    <!--Spring.Context.Support.ContextRegistry 的型別初始值設定項引發異常。-->
    <!--註釋掉此配置節,否則會報上述異常-->
    <!--<startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
    </startup>-->  
    <!--Spring配置-->
    <configSections>
        <sectionGroup name="spring">
            <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
            <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
        </sectionGroup>
    </configSections>

    <spring>
        <context>
            <resource uri="config://spring/objects"/>
        </context>
        <objects xmlns="http://www.springframework.net">
            <!--配置通知類LogBeforeAdvice-->
            <object id="beforeAdvice" type="AOPExample.LogBeforeAdvice,AOPExample"/>         
            <!--通過ProxyFactoryObject 顯式建立AOP代理-->
            <object id="userServiceProxy" type="Spring.Aop.Framework.ProxyFactoryObject">
                <!--指定代理的真實物件-->
                <property name="Target">
                    <object type="AOPExample.UserService,AOPExample"/>
                </property>
                <!--指定具體通知類-->
                <property name="InterceptorNames">
                    <list>
                        <!--指定具體通知類,和前面配置的id一致-->
                        <value>beforeAdvice</value>
                    </list>
                </property>
            </object>
        </objects>
    </spring>
</configuration>

客戶端

    class Program
    {
        static void Main(string[] args)
        {
            //例項化使用者
            User enUser = new User()
            {
                Name ="Jenny",
                Age=15
            };

            //獲得Spring容器上下文
            IApplicationContext context = ContextRegistry.GetContext();
            //從配置檔案獲得由ProxyFactoryObject生成的代理類
            //需要修改客戶端,原來是直接呼叫真實物件,現在是呼叫代理
            IUserService userServiceProxy = (IUserService)context["userServiceProxy"];
            userServiceProxy.GetUserInfo(enUser);

        }
    }

執行結果
這裡寫圖片描述

總結

  • 優點:通過ProxyFactoryObject 建立代理類,省去自己手動建立代理類;
  • 缺點1:如果有多個目標物件,每個都需要在配置檔案中配置;
  • 缺點2:客戶端呼叫時,由原來呼叫目標物件,變成呼叫代理物件,需要修改客戶端程式碼。

相關推薦

AOP系列()——ProxyFactoryObject 建立AOP代理

AOP概念   Aspect Oriented Programming,面向切面程式設計,可以通過預編譯方式和執行期動態代理,實現在不修改原始碼的情況下給程式動態統一新增功能的一種技術。 前

Castle AOP 系列():對類方法呼叫的攔截(有原始碼)

Castle的相關網站: 在Castle的2.5以上版本,已經將 Castle.DynamicProxy2.dll 裡有內容,整合到 Castle.Core.dll 中。 所以,朋友們,不需要再去哪裡找Castle.DynamicProxy2.dll了。 當然,除非你使

GC導致的High CPU問題處理過程

.cn images 雲服務 obj 日誌 驚人的 什麽 cati ros 項目現場反饋系統出現性能問題,具體表現為:所有的客戶端響應極其卡頓。 第一反應推測,難道是DB層面出現阻塞?檢查v$session會話狀態及等待類型未見異常,應該可以排除DB層面原因導致的可能。 繼

Vue.js系列():Vue專案建立詳解

引言 Vue.js作為目前最熱門最具前景的前端框架之一,其提供了一種幫助我們快速構建並開發前端專案的新的思維模式。本文旨在幫助大家認識Vue.js,並詳細介紹使用vue-cli腳手架工具快速的構建Vue專案,以及對專案目錄結構的解釋說明,使大家清晰的瞭解Vue專案的開發流程。 簡介 Vue (讀音 /vj

Spring AOP系列代理建立

Spring Boot AOP系列之動態代理建立 序言:在本文中,我會講到Spring中如何建立動態代理,如何利用jdk或者cglib來建立動態代理,但是同時,我也會提及如何手動建立代理,這將有助於我們瞭解動態代理的原理。我們先來講講如何手動建立吧

net core天馬行空系列:原生DI+AOP實現spring boot註解程式設計

       寫過spring boot之後,那種無處不在的註解讓我非常喜歡,比如屬性注入@autowire,配置值注入@value,宣告式事物@Transactional等,都非常簡潔優雅,那麼我就在想,這些在net core裡能實現麼?經過一番摸索,終於實現並整理成

Spring aop學習整理(spring in action)():了解AOP

進入 一起 table return 問題 匹配 核心 before cti   切面能幫助我們模塊化橫切關註點。簡而言之,橫切關註點可以被描述為影響應用多處的功能。例如,安全就是一個橫切關註點,應用中的許多方法都會涉及到安全規則。圖4.1直觀呈現了橫切關註點的概念。  

轉載《Spring AOP中pointcut expression表達解析 及匹配多個條件》

targe 組合 man fin rgs acc ans value account 原文地址:https://www.cnblogs.com/rainy-shurun/p/5195439.html 原文 Pointcut 是指那些方法需要被執行"AOP",是由"Poi

Spring AOP的實現:建立AopProxy代理物件

        前面我們講述了AOP的基本知識以及在Spring AOP機制中的一些基本的資料結構及其功能。下面開始正式的講述Spring AOP的實現部分。 來看一下這個以ProxyFactory為中心的繼承關係圖 可以將P

Spring原始碼解析(十五)——AOP原理——建立aop代理

   * AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】    的作用:  * 1)、每一個bean建立之前,呼叫postProce

AOP概述(什麼是AOP?)——Spring AOP

AOP概述–什麼是AOP 面向切面程式設計,能夠讓我們在不影響原有功能的前提下,為軟體橫向擴充套件功能 。AOP解決了OOP中遇到的一些問題,是OOP的延續和擴充套件。 什麼是橫向擴充套件? 軟體專案中的三層架構分為持久層,業務層和表示層。當我們處理一個任務時,是從表示

SQLServer之建立事務

顯式事務定義 顯式事務以 BEGIN TRANSACTION 語句開始,並以 COMMIT 或 ROLLBACK 語句結束。 備註 BEGIN TRANSACTION 使 @@TRANCOUNT 按 1 遞增。 BEGIN TRANSACTION 代表一點,由連線引用的資料在該點

建構函式建立物件作為引數 / 使用函式表示法的型別轉換

看個建構函式建立隱式物件作為引數的例子 #include<iostream> using namespace std; class A { int a; int b; public: A() { cout << "建構函式" << endl; };

AOP系列學習

本文全部轉載自大師兄的部落格: https://blog.csdn.net/qq_27093465/article/category/7337735 AOP學習前奏 註解之概念的理解: https://blog.csdn.net/qq_27093465/article/details/5

文讀懂 AOP | 你想要的最全面 AOP 方法探討

前前言 相信大家在入門 AOP 時,常常被繁多的術語、方法和框架繞暈。AOP 好像有點耳熟?Javaseopt 是個什麼?Javassist 又是啥?Dexposed、APT 也是 AOP?本篇將輔助你快速理清概念,掌握 AOP 思想,找到最適合自己業務場景的 AOP 方法。 前言 上

ECMA:JavaScript中AOP種實現

相比Javascript,果然還是Java好用的多。 隨著JavaScript的發展,目前的JS已經支援Class等多種新的關鍵字,當然,也就多了很多新的坑。 今天發現某個專案中,突然出現了很多JWT異常,觀察了一下,JWT不知道為啥變成了null,不知道是那個前輩搞的,如果在發出請求之

手寫Spring註解事務(利用AOP技術 + 註解 + Spring程式設計事務)

1.參考下面的文章搭建一個無事務管理的SSM操作資料庫的框架       Spring 使用Druid資料來源 整合 Mybatis 2.AOP技術參考       AOP技術應用實現 3.第一步首先實現Sprin

響應程式設計系列《規約》

提升開發效率,降低維護成本一直是開發團隊永恆不變的宗旨。近兩年來國內的技術圈子中越來越多的開始提及ReactiveX,越來越多的應用和麵試中都會有ReactiveX,響應式程式設計中RxJava可謂如魚得水。 目錄 1. 背景

Spring 原始碼分析(三) —— AOPAOP原理

AOP概論         AOP(Aspect-Oriented Programming,面向切面的程式設計),談起AOP,則一定會追溯到OOP(Object Oriented Programming,面向物件程式設計),因為AOP可以說是對OOP的補充和完善,而這一切的

Spring面向切面程式設計(AOP)原理之使用JDK實現動態代理

什麼是面向切面程式設計? AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP(面向物件程式設計)的延續,是軟體開發中的一個熱點,也是Spr