1. 程式人生 > >Spring簡介之基本概念 AOP、IOC

Spring簡介之基本概念 AOP、IOC

1、基本概念理解 AOP:Aspect Oriented Programming:面向切面程式設計 OOP:Object Oriented Programming:面向物件程式設計 話不多說直接上圖 在這裡插入圖片描述為一些OOP 物件加入一些統一的方法

橫切開 一些封裝好的物件 ,將對 一些公共的與業務關係不大的 整理成一個可重用模組,並將其名為“Aspect”,即方面。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處都基本相似。比如許可權認證、日誌、事務處理。Aop 的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。

AOP 的應用場景

Authentication 許可權 Caching 快取 Context passing 內容傳遞 Error handling 錯誤處理 Lazy loading 懶載入 Debugging 除錯 logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準 Performance optimization 效能優化 Persistence 持久化 Resource pooling 資源池 Synchronization 同步 Transactions 事務

AOP用法 AOP在spring中有兩種配置方式,一是xml配置的方式,二是自動註解的模式。

  • xml配置

1、 定義切面類 在xml中,我們使用如下AOP配置元素宣告切面

public class XmlAopDemoUserLog {
//    方法執行前通知
    public void beforeLog() {
        System.out.println("開始執行前置通知  日誌記錄");
    }
//    方法執行完後通知
    public void afterLog() {
        System.out.println("開始執行後置通知 日誌記錄");
    }
//    執行成功後通知
    public void afterReturningLog() {
        System.out.println("方法成功執行後通知 日誌記錄");
    }
//    丟擲異常後通知
    public void afterThrowingLog() {
        System.out.println("方法丟擲異常後執行通知 日誌記錄");
    }

//    環繞通知
    public Object aroundLog(ProceedingJoinPoint joinpoint) {
        Object result = null;
        try {
            System.out.println("環繞通知開始 日誌記錄");
            long start = System.currentTimeMillis();

            //有返回引數 則需返回值
            result =  joinpoint.proceed();

            long end = System.currentTimeMillis();
            System.out.println("總共執行時長" + (end - start) + " 毫秒");
            System.out.println("環繞通知結束 日誌記錄");
        } catch (Throwable t) {
            System.out.println("出現錯誤");
        }
        return result;
    }
}

2 、xml宣告切面並呼叫

<bean id="xmlAopDemoUserLog" class="com.ganji.demo.service.aspect.XmlAopDemoUserLog"></bean>
<aop:config>
    <aop:aspect ref="xmlAopDemoUserLog"> <!--指定切面-->
        <!--定義切點-->
        <aop:pointcut id="logpoint" expression="execution(* com.ganji.demo.service.user.UserService.GetDemoUser(..))"></aop:pointcut>
        <!--定義連線點-->
        <aop:before pointcut-ref="logpoint" method="beforeLog"></aop:before>
        <aop:after pointcut-ref="logpoint" method="afterLog"></aop:after>
        <aop:after-returning pointcut-ref="logpoint" method="afterReturningLog"></aop:after-returning>
        <aop:after-throwing pointcut-ref="logpoint" method="afterThrowingLog"></aop:after-throwing>
    </aop:aspect>
</aop:config>

3、 在controller下呼叫,呼叫具體如下

DemoUserEntity demoUser=userService.GetDemoUser(1);
  • 自動註解AOP 1、 配置自動代理
<aop:aspectj-autoproxy />

2、使用@Aspect註解

@Aspect
@Service
public class XmlAopDemoUserLog {

// 配置切點 及要傳的引數   
    @Pointcut("execution(* com.ganji.demo.service.user.UserService.GetDemoUser(..)) && args(id)")
    public void pointCut(int id)
    {

    }

// 配置連線點 方法開始執行時通知
    @Before("pointCut(id)")
    public void beforeLog(int id) {
        System.out.println("開始執行前置通知  日誌記錄:"+id);
    }
//    方法執行完後通知
    @After("pointCut(id)")
    public void afterLog(int id) {
        System.out.println("開始執行後置通知 日誌記錄:"+id);
    }
//    執行成功後通知
    @AfterReturning("pointCut(id)")
    public void afterReturningLog(int id) {
        System.out.println("方法成功執行後通知 日誌記錄:"+id);
    }
//    丟擲異常後通知
    @AfterThrowing("pointCut(id)")
    public void afterThrowingLog(int id) {
        System.out.println("方法丟擲異常後執行通知 日誌記錄"+id);
    }

//    環繞通知
    @Around("pointCut(id)")
    public Object aroundLog(ProceedingJoinPoint joinpoint,int id) {
        Object result = null;
        try {
            System.out.println("環繞通知開始 日誌記錄"+id);
            long start = System.currentTimeMillis();

            //有返回引數 則需返回值
            result =  joinpoint.proceed();

            long end = System.currentTimeMillis();
            System.out.println("總共執行時長" + (end - start) + " 毫秒");
            System.out.println("環繞通知結束 日誌記錄");
        } catch (Throwable t) {
            System.out.println("出現錯誤");
        }
        return result;
    }
}