⑴ spring中的aop 是怎麼面向切面編程的
Spring面向切面編程(AOP)
1 spring容器中bean特性
Spring容器的javabean對象默認是單例的。
通過在xml文件中,配置可以使用某些對象為多列。
Spring容器中的javabean對象默認是立即載入(立即實例化:spring載入完成,立即創建對象)
scope:屬性
singleton:默認值為單例,默認也是立即載入,在載入完成spring容器的時候,bean對象已經創建完成
prototype:多例的,默認懶載入,spring容器載入完成的時候,不會創建bean的對象,只有從容器獲得bean對象的時候,才進行bean對象的實例化
request: 將創建的javabean對象,封裝到request范圍
session:將創建的javabean對象,封裝到session范圍
Spring容器bean的對象生命周期:
Bean對象的創建一直到銷毀為bean的生命周期。
生命周期的開始:
如果為單例,由載入完spring容器開始
如果為多例,由從容器獲得bean對象開始
實例化
初始化
服務
銷毀(單例:關閉容器的時候,多例由jvm自動回收)
2 spring的AOP面向切面編程
2.1 模擬銀行轉賬業務
需求:實現銀行的轉賬功能,在轉賬的時候需要完成
1 身份認證(登陸)
2 許可權的驗證
3 轉賬實現
4 歷史交易記錄,
分析:1,2,4三個功能對於銀行的業務,屬於公共的功能(共性的功能)
在功能實現的時候,需要將1,2,4抽取出來,單獨實現,
做到了將共性的功能和核心的業務功能進行了分離
通過動態代理實現:共性的功能和核心業務功能的合並,產生核心業務對象的
在代碼實現的時候,進行了功能實現的分離:
代碼開發的進行分離,程序在運行的時候進行合並。
2.2 springAOP的思想
在系統開發中,將系統的共性的公共的功能獨立實現,在程序運行的過程中,將共性功能和核心的業務功能,進行整合。
好處:
1 完成共性功能和核心業務功能的解耦合
2 提供共性功能的復用性。
2.3springAOP的概念
Aspect切面:封裝共性功能的(增強功能的)類
Advice通過:切面類中封裝的增強功能的方法。
PointCut:切入點,是一個集合的概念,該集合的表達使用一個正則表達式表達
所有核心業務對象的所有方法的前後(事務處理AOP典型的應用)
JoinPoint:連接點,程序中需要加入advice的地方,而且正在執行的ponitCut
織入(Weaving):將aspect和核心業務對象,進行整合的過程。
3 springAOP的實現
3.1通過特定介面實現
Aop通知的類型:
Before:前置通知
After:後置通知
Around:環繞通知
Throwing:異常通知
需求:實現在業務對象中的方法執行的時候,記錄日誌功能
3.1.1前置通知
packageorg.guangsoft.utils;
importjava.lang.reflect.Method;
importjava.util.Arrays;
importjava.util.Date;
importorg.springframework.aop.MethodBeforeAdvice;
/****
*前置增強:
*MethodBeforeAdvice介面表示重寫的方法為前置advice
****/
{
@Override
publicvoidbefore(Methodmethod,
Object[]args,Objectobj)
throwsThrowable
{
System.out.println(method);
System.out.println(Arrays.toString(args));
System.out.println(obj);
System.out.println("BeforeLog-------------"+newDate());
}
}
AOP配置:
<?xmlversion="1.0"encoding="UTF-8"?>
<!--到入xml文件的約束-->
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"xmlns:p="http://www.springframework.org/schema/p"
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-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
<!--實例化BeforeLog對象-->
<beanid="bf"class="org.guangsoft.utils.BeforeLog"></bean>
<!--實例化service對象-->
<beanid="us"class="org.guangsoft.service.impl.UsersServiceImpl"/>
<!--進行aop的配置,產生代理對象-->
<aop:config>
<!--聲明切入點-->
<aop:pointcutexpression="execution(*org.guansoft.service.impl.*.*(..))"
id="pc"/>
<!--織入將通知和切入點進行合並(切面+核心業務對象)-->
<aop:advisoradvice-ref="bf"pointcut-ref="pc"/>
</aop:config>
</beans>
3.1.2後置通知
對業務對象的方法進行後增強。
packageorg.guangsoft.utils;
importjava.lang.reflect.Method;
importjava.util.Date;
importorg.springframework.aop.AfterReturningAdvice;
/***
*後置通知
****/
{
@Override
publicvoidafterReturning(Objectobj1,//obj1接收目標方法的返回值
Methodmethod,
Object[]args,
Objectobj2)throwsThrowable
{
//System.out.println(obj1+"----------------------"+obj2);
System.out.println("AfterLog-------------------"+newDate());
}
}
AOP配置:
<?xmlversion="1.0"encoding="UTF-8"?>
<!--到入xml文件的約束-->
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"xmlns:p="http://www.springframework.org/schema/p"
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-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
<!--實例化BeforeLog對象-->
<beanid="bf"class="org.guangsoft.utils.BeforeLog"></bean>
<beanid="af"class="org.guangsoft.utils.AfterLog"></bean>
<!--實例化service對象-->
<beanid="us"class="org.guangsoft.service.impl.UsersServiceImpl"/>
<!--進行aop的配置,產生代理對象-->
<aop:config>
<!--聲明切入點-->
<aop:pointcutexpression="execution(*org.guangsoft.service.impl.*.*(..))"
id="pc"/>
<!--織入將通知和切入點進行合並(切面+核心業務對象)-->
<aop:advisoradvice-ref="bf"pointcut-ref="pc"/>
<aop:advisoradvice-ref="af"pointcut-ref="pc"/>
</aop:config>
</beans>
3.1.3環繞通知
packageorg.guangsoft.utils;
importjava.lang.reflect.Method;
importjava.util.Arrays;
importjava.util.Date;
importorg.aopalliance.intercept.MethodInterceptor;
importorg.aopalliance.intercept.MethodInvocation;
/***
*環繞通知
****/
{
/**
*MethodInvocation中封裝了目標對象,調用的方法,方法需要的參數
****/
@Override
publicObjectinvoke(MethodInvocationmi)throwsThrowable
{
Methodmethod=mi.getMethod();
Object[]args=mi.getArguments();
Objectobj=mi.getThis();
System.out.println(method);
System.out.println(Arrays.toString(args));
System.out.println(obj);
System.out.println("around------before--------"+newDate());
Objectrv=method.invoke(obj,args);//調用目標對象的方法,放行
System.out.println("around------after--------"+newDate());
returnrv;
}
}
AOP配置:同上
3.1.4 異常通知
packageorg.guangsoft.utils;
importjava.util.Date;
importorg.springframework.aop.ThrowsAdvice;
/****
*異常通知
***/
{
/***
*該類中的方法參考AfterReturningAdvice寫
*該參數是用來接收異常信息的
****/
publicvoidafterThrowing(Throwableex)throwsThrowable
{
//System.out.println(obj1+"----------------------"+obj2);
System.out.println("ExceptionLog-----------"+ex.getMessage()
+"--------"+newDate());
}
}
Pointcut:核心業務對象
Advice:通知
⑵ php怎麼實現面向切面編程
下面是向切面式組件源碼,是根據AOP的思路設計的:
<?php
if (function_exists('__autoload')) {
trigger_error("Extension: It looks like your code is using an __autoload() function. Extension uses spl_autoload_register() which will bypass your __autoload() function and may break autoloading.", E_USER_WARNING);}
spl_autoload_register(array('ExtensionFactory', 'autoload'));class ExtensionFactory {
private static $extFamily = null;
private static $_classes = array(
'Extension' => '/Extension.php',
'ExtensionFamily' => '/ExtensionFamily.php'
);
/**
* Class autoloader. This method is provided to be invoked within an* __autoload() magic method.
* @param string $className The name of the class to load.
*/
public static function autoload() {
foreach(self::$_classes as $v){
require_once dirname(__FILE__) . $v;
}
}
/**
* 必須先調用此方法來實例化擴展族,才能調用addExtension\removeExtension等* @return ExtensionFamily
*/
public static function createExtension(){self::$extFamily = new ExtensionFamily();return self::$extFamily;
}
public static function removeExtension($extName){if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");return false;
}else{
unset(self::$extFamily->_extensionArray[$extName]);}
}
public static function addExtension($extName, Extension $ext){if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");return false;
}else{
self::$extFamily->_extensionArray[$extName] = $ext;}
}
public static function removeAllExtension(){if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");return false;
}else{
foreach(self::$extFamily->_extensionArray as $extName=>$ext){unset(self::$extFamily->_extensionArray[$extName]);}
}
}
}
<?php
if (function_exists('__autoload')) {
trigger_error("Extension: It looks like your code is using an __autoload() function. Extension uses spl_autoload_register() which will bypass your __autoload() function and may break autoloading.", E_USER_WARNING);}
spl_autoload_register(array('ExtensionFactory', 'autoload'));class ExtensionFactory {
private static $extFamily = null;
private static $_classes = array(
'Extension' => '/Extension.php',
'ExtensionFamily' => '/ExtensionFamily.php'
);
/**
* Class autoloader. This method is provided to be invoked within an* __autoload() magic method.
* @param string $className The name of the class to load.
*/
public static function autoload() {
foreach(self::$_classes as $v){
require_once dirname(__FILE__) . $v;
}
}
/**
* 必須先調用此方法來實例化擴展族,才能調用addExtension\removeExtension等* @return ExtensionFamily
*/
public static function createExtension(){self::$extFamily = new ExtensionFamily();return self::$extFamily;
}
public static function removeExtension($extName){if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");return false;
}else{
unset(self::$extFamily->_extensionArray[$extName]);}
}
public static function addExtension($extName, Extension $ext){if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");return false;
}else{
self::$extFamily->_extensionArray[$extName] = $ext;}
}
public static function removeAllExtension(){if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");return false;
}else{
foreach(self::$extFamily->_extensionArray as $extName=>$ext){unset(self::$extFamily->_extensionArray[$extName]);}
}
}
}
<?php
/**
* 擴展家族
*
* @author Mr.Jin
*/
class ExtensionFamily implements Extension{public $_extensionArray = array();
/**
*
* @param type $extName 擴展名
* @param Extension $ext 實現Extension的對象*/
public function addExtension($extName, Extension $ext){$this->_extensionArray[$extName] = $ext;
}
public function beforeAppend(&$params){
foreach($this->_extensionArray as $ext){
$ext->beforeAppend($params);
}
}
public function afterAppend(&$params) {
foreach($this->_extensionArray as $ext){
$ext->afterAppend($params);
}
}
}
?>
<?php
/**
* 擴展家族
*
* @author Mr.Jin
*/
class ExtensionFamily implements Extension{public $_extensionArray = array();
/**
*
* @param type $extName 擴展名
* @param Extension $ext 實現Extension的對象*/
public function addExtension($extName, Extension $ext){$this->_extensionArray[$extName] = $ext;
}
public function beforeAppend(&$params){
foreach($this->_extensionArray as $ext){
$ext->beforeAppend($params);
}
}
public function afterAppend(&$params) {
foreach($this->_extensionArray as $ext){
$ext->afterAppend($params);
}
}
}
?>
<?php
/**
* 擴展介面
*
* @author Mr.Jin
*/
interface Extension {
public function beforeAppend(&$params);
public function afterAppend(&$params);
}
?>
<?php
/**
* 擴展介面
*
* @author Mr.Jin
*/
interface Extension {
public function beforeAppend(&$params);
public function afterAppend(&$params);
}
?>
以上三個文件實現了簡單的AOP組件。
下面是Demo:
<?php
/**
* 自定義Extension
* 用戶積分Extension
* 根據用戶是否登錄,決定此次消費是否記錄用戶積分*
* @author Mr.Jin
*/
class ExampleExtension implements Extension {public $check=false;
public function beforeAppend(&$isLogin) {if($isLogin){
$this->check = true;
}
}
public function afterAppend(&$pointer) {
if($this->check){
//add pointer
}else{
echo '未登錄用戶,積分不錄入';
return;
}
}
}
?>
<?php
/**
* 自定義Extension
* 用戶積分Extension
* 根據用戶是否登錄,決定此次消費是否記錄用戶積分*
* @author Mr.Jin
*/
class ExampleExtension implements Extension {public $check=false;
public function beforeAppend(&$isLogin) {if($isLogin){
$this->check = true;
}
}
public function afterAppend(&$pointer) {
if($this->check){
//add pointer
}else{
echo '未登錄用戶,積分不錄入';
return;
}
}
}
?>
demo.php
<?php
require_once('ExtensionFactory.php');//導入組件本身require_once('ExampleExtension.php');//導入擴展$ext = ExtensionFactory::createExtension();ExtensionFactory::addExtension('example', new ExampleExtension());//積分錄入功能/*
* 按照需求的變化,可以增加相應的Extension.
* eg.
* 新需求:新增會員類型,根據不同類型,進行價格優惠。
* 實現思路:
* 一、建立卡號類型工廠
* 二、建立SeniorMemberExtension、PuTongMeberExtension.
* 三、工廠方法根據會員類型addExtension
*/
$isLogin = false; //假設用戶未登錄
$ext->beforeAppend($isLogin);
/**
* 面向切面編程,最重要一點是:必須先分析出整個業務處理中,哪個才是重點。
* 這里的重點是訂單的入庫。
* 在訂單入庫之前可能業務邏輯不斷增加,例如:登錄驗證、卡上余額驗證等* 在訂單入庫之後:積分處理、訂單監控等
*/
echo "此處是主要業務邏輯:訂單入庫\r\n";
$pointer = 100;
$ext->afterAppend($pointer);
<?php
require_once('ExtensionFactory.php');//導入組件本身require_once('ExampleExtension.php');//導入擴展$ext = ExtensionFactory::createExtension();ExtensionFactory::addExtension('example', new ExampleExtension());//積分錄入功能/*
* 按照需求的變化,可以增加相應的Extension.
* eg.
* 新需求:新增會員類型,根據不同類型,進行價格優惠。
* 實現思路:
* 一、建立卡號類型工廠
* 二、建立SeniorMemberExtension、PuTongMeberExtension.
* 三、工廠方法根據會員類型addExtension
*/
$isLogin = false; //假設用戶未登錄
$ext->beforeAppend($isLogin);
/**
* 面向切面編程,最重要一點是:必須先分析出整個業務處理中,哪個才是重點。
* 這里的重點是訂單的入庫。
* 在訂單入庫之前可能業務邏輯不斷增加,例如:登錄驗證、卡上余額驗證等* 在訂單入庫之後:積分處理、訂單監控等
*/
echo "此處是主要業務邏輯:訂單入庫\r\n";
$pointer = 100;
$ext->afterAppend($pointer);
⑶ 面向切面編程和面向介面編程的區別
談談自己的理解吧:
面向切面編程:
手段:分離業務的主邏輯和次邏輯的一種思想。
目的:解決的是邏輯分離問題(主邏輯和次邏輯分開,其實主要是分離業務邏輯和非業務邏輯分開)。
案例:我們開發項目的時候基本都要去連接資料庫操作數據等,但是都會涉及到事務的提交,這時我們就用到了面向切面編程,我們在業務層只寫自己的業務邏輯,提交事務這一塊統一的動作我們就濃縮到了一塊兒統一處理,形象一點比喻就是我們做什麼事之前都以一個准備動作或結束動作的時候就把它統一起來,只關注我們要完成的事,這些准備動作統一完成!
類似的面向切面編程案例還有:系統日誌的記錄、請求的攔截等
面向介面編程:
手段:通過介面規約對象的屬性和方法,是面向對象一部分。
目的:統一標准問題,讓大家不至於各行其事而對代碼的可讀性造成影響(公用部分行為)。
案例:其實這個比較好解釋,就是有一件事,需要大家去完成,但是給你規定了完成的方式,你只能怎麼去做,這時我們當中任何一個人都能去完成這件事,只不過因人而異會有效率和風格的差異,但是都是按照事先的規定來的!比如:讓你去給資料庫添加一行數據返回受影響的行數,這里大家都去實現介面寫SQL,中間可能會有差異,但是最後都得返回一個int類型的受影響行數回來
大體意思就是說:介面給我們規定了完成一個任務的標准,但是具體過程不限制,任何人都能通過遵循的規定去完成這件事!這樣擴展性就很強!
個人水平有限,如果不滿意請參考:網頁鏈接
⑷ 誰能解釋一下java面向切面編程的思想 以及具體的使用方式
面向切面編程(AOP),就是關注程序運行的過程,切面就是要把方法切開,分別執行前,執行中,執行後(可能更細化)等多個步驟,分別針對這三個階段進行處理。以獲得邏輯過程中各部分之間低耦合性的隔離效果。
具體使用場景:
事務管理:我們在操作資料庫的時候需要在操作前打開事務,結束後提交事務(或回滾事務),按往常的編碼方式,我們會在每個方法前、後都添加一些事務操作的重復的代碼,使得每個類都與事務操作相耦合;而使用了AOP,代碼上看上去就是直接操作的資料庫,而我們通過某種機制,可讓代碼在你不察覺的情況下進行了事務開啟和提交(或回滾),事實上Spring就提供了這種事務機制。
差不多的場景還有日誌的記錄
⑸ 如何在Spring框架中進行面向切面編程
什麼是DI(ioc)機制?
依賴注入(Dependecy Injection)和控制反轉(Inversion of Control)是同一個概念,具體的講:當某個角色
需要另外一個角色協助的時候,在傳統的程序設計過程中,通常由調用者來創建被調用者的實例。但在spring中
創建被調用者的工作不再由調用者來完成,因此稱為控制反轉。創建被調用者的工作由spring來完成,然後注入調用者
因此也稱為依賴注入。
spring以動態靈活的方式來管理對象 , 注入的兩種方式,設置注入和構造注入。
設置注入的優點:直觀,自然
構造注入的優點:可以在構造器中決定依賴關系的順序。
什麼是AOP?
面向切面編程(AOP)完善spring的依賴注入(DI),面向切面編程在spring中主要表現為兩個方面
面向切面編程提供聲明式事務管理
2.spring支持用戶自定義的切面
⑹ 面向切面編程的簡介
Aspect Oriented Programming(AOP),面向切面編程,是一個比較熱門的話題。AOP主要實現的目的是針對業務處理過程中的切面進行提取,它所面對的是處理過程中的某個步驟或階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果。比如我們最常見的就是日誌記錄了,舉個例子,我們現在提供一個服務查詢學生信息的,但是我們希望記錄有誰進行了這個查詢。如果按照傳統的OOP的實現的話,那我們實現了一個查詢學生信息的服務介面(StudentInfoService)和其實現類(StudentInfoServiceImpl.java),同時為了要進行記錄的話,那我們在實現類(StudentInfoServiceImpl.java)中要添加其實現記錄的過程。這樣的話,假如我們要實現的服務有多個呢?那就要在每個實現的類都添加這些記錄過程。這樣做的話就會有點繁瑣,而且每個實現類都與記錄服務日誌的行為緊耦合,違反了面向對象的規則。那麼怎樣才能把記錄服務的行為與業務處理過程中分離出來呢?看起來好像就是查詢學生的服務自己在進行,但卻是背後日誌記錄對這些行為進行記錄,並且查詢學生的服務不知道存在這些記錄過程,這就是我們要討論AOP的目的所在。AOP的編程,好像就是把我們在某個方面的功能提出來與一批對象進行隔離,這樣與一批對象之間降低了耦合性,可以就某個功能進行編程。
⑺ 面向切面編程
「面向切面編程」。只有當你真正的理解OOP之後,才可以理解AOP(面向切面編程)的思想。
這個思想,不是一兩句就能將的明白的。用個生活中的例子:
人的手可以寫字,並且可以用很多中筆來寫字。例如,鋼筆、鉛筆、毛筆等等。(這里抽象的說)如果我們要用到人的手寫字的時候,就必須提供給手很多中筆,可是每種筆的類型有各自不同,我們說筆有很多不同的屬性的功能。如果才能讓我們的手拿到任何一種筆都可以寫字呢,我們可以這樣做。將鋼筆、鉛筆、毛筆等等筆定義一種公共的「筆」的類型,讓我們的手在使用筆的時候,只需要知道要使用一個筆來寫字,而不需要關心使用什麼筆來寫。而決定給這只手用的筆的類型,就是你的事情了。
抽象成簡單的代碼:
interface Pen{}
class GangBi implements Pen{}
class MaoBi implements Pen{}
class QianBi implements Pen{}
class Human{
void usePen(Pen pen){}
}
這個概念超級抽象。不過,學習Spring框架可以快速的來理解這個概念。
⑻ 面向切面編程 面向介面編程 面向抽象編程 面向對象編程
面向切面的編程 主要實現的目的是針對業務處理過程中的切面進行提取,它所面對的是處理過程中的某個步驟或階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果。
比如我們最常見的就是日誌記錄了,舉個例子,我們現在提供一個服務查詢學生信息的,但是我們希望記錄有誰進行了這個查詢。如果按照傳統的OOP的實現的話,那我們實現了一個查詢學生信息的服務介面(StudentInfoService)和其實現類(StudentInfoServiceImpl.java),同時為了要進行記錄的話,那我們在實現類(StudentInfoServiceImpl.java)中要添加其實現記錄的過程。這樣的話,假如我們要實現的服務有多個呢?那就要在每個實現的類都添加這些記錄過程。這樣做的話就會有點繁瑣,而且每個實現類都與記錄服務日誌的行為緊耦合,違反了面向對象的規則。
那麼怎樣才能把記錄服務的行為與業務處理過程中分離出來呢?看起來好像就是查詢學生的服務自己在進行,但是背後日誌記錄對這些行為進行記錄,但是查詢學生的服務不知道存在這些記錄過程,這就是我們要討論AOP的目的所在。AOP的編程,好像就是把我們在某個方面的功能提出來與一批對象進行隔離,這樣與一批對象之間降低了耦合性,可以就某個功能進行編程。
⑼ 什麼是面向切面編程AOP
面向切面編程(AOP是Aspect Oriented Program的首字母縮寫) ,我們知道,面向對象的特點是繼承、多態和封裝。而封裝就要求將功能分散到不同的對象中去,這在軟體設計中往往稱為職責分配。實際上也就是說,讓不同的類設計不同的方法。這樣代碼就分散到一個個的類中去了。這樣做的好處是降低了代碼的復雜程度,使類可重用。
但是人們也發現,在分散代碼的同時,也增加了代碼的重復性。什麼意思呢?比如說,我們在兩個類中,可能都需要在每個方法中做日誌。按面向對象的設計方法,我們就必須在兩個類的方法中都加入日誌的內容。也許他們是完全相同的,但就是因為面向對象的設計讓類與類之間無法聯系,而不能將這些重復的代碼統一起來。
也許有人會說,那好辦啊,我們可以將這段代碼寫在一個獨立的類獨立的方法里,然後再在這兩個類中調用。但是,這樣一來,這兩個類跟我們上面提到的獨立的類就有耦合了,它的改變會影響這兩個類。那麼,有沒有什麼辦法,能讓我們在需要的時候,隨意地加入代碼呢?這種在運行時,動態地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程。
一般而言,我們管切入到指定類指定方法的代碼片段稱為切面,而切入到哪些類、哪些方法則叫切入點。有了AOP,我們就可以把幾個類共有的代碼,抽取到一個切片中,等到需要時再切入對象中去,從而改變其原有的行為。
這樣看來,AOP其實只是OOP的補充而已。OOP從橫向上區分出一個個的類來,而AOP則從縱向上向對象中加入特定的代碼。有了AOP,OOP變得立體了。如果加上時間維度,AOP使OOP由原來的二維變為三維了,由平面變成立體了。從技術上來說,AOP基本上是通過代理機制實現的。
AOP在編程歷史上可以說是里程碑式的,對OOP編程是一種十分有益的補充。
⑽ 什麼是面向切面編程
「面向切面編程」。只有當你真正的理解OOP之後,才可以理解AOP(面向切面編程)的思想。
這個思想,不是一兩句就能將的明白的。用個生活中的例子:
人的手可以寫字,並且可以用很多中筆來寫字。例如,鋼筆、鉛筆、毛筆等等。(這里抽象的說)如果我們要用到人的手寫字的時候,就必須提供給手很多中筆,可是每種筆的類型有各自不同,我們說筆有很多不同的屬性的功能。如果才能讓我們的手拿到任何一種筆都可以寫字呢,我們可以這樣做。將鋼筆、鉛筆、毛筆等等筆定義一種公共的「筆」的類型,讓我們的手在使用筆的時候,只需要知道要使用一個筆來寫字,而不需要關心使用什麼筆來寫。而決定給這只手用的筆的類型,就是你的事情了。
抽象成簡單的代碼:
interface Pen{}
class GangBi implements Pen{}
class MaoBi implements Pen{}
class QianBi implements Pen{}
class Human{
void usePen(Pen pen){}
}
這個概念超級抽象。不過,學習Spring框架可以快速的來理解這個概念。