1. 程式人生 > 實用技巧 >java網路程式設計基礎

java網路程式設計基礎

Spring AOP

3.1 Spring AOP簡介

3.1.1 AOP

Aspect-Oriented Programming,面向切面程式設計。是傳統的OOP程式設計的一個重要的補充。OOP程式設計,只能子類繼承父類的縱向重用。

AOP採用的是橫向抽取機制。將分散重複的程式碼抽離出來,在程式編譯或者執行的過程,將程式碼用到需要的執行地方。

3.1.2 AOP術語

Aspect(切面)

JoinPoint(連線點)

Pointcut(切入點)

Advice(通知增強處理)

Target Object(目標物件)

Proxy(代理)

Weaving(織入)

3.2 AspectJ開發

基於XML配置

1.UserDao.java

package com.sty.dao;

public interface UserDao {

    //新增使用者
     void add();

    //刪除使用者
    void delete();
}

2.UserDaoImpl.java

package com.sty.dao;

public class UserDaoImpl implements UserDao {
    public void add() {
        System.out.println("增加一個使用者");
    }

    public void delete() {
        System.out.println("刪除一個使用者");
    }
}

3.MyAspect.java

package com.sty.dao.aspect;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.lang.NonNull;


/*
* 面向切面類
* */
public class MyAspect {
    /*1.前置通知*/
    public void myBefore(@NonNull JoinPoint  joinPoint){
        System.out.println("前置通知:模擬執行許可權。。。。。");
        System.out.println("目標類是:"+joinPoint.getTarget());
        System.out.println(","+"被植入增強處理的目標方法是"+joinPoint.getSignature().getName());
    }

    /*2.後置通知*/
    public void myAfterReturning(@NonNull JoinPoint joinPoint){
        System.out.println("後置通知:模擬記錄日誌");
        System.out.println("被植入增強處理的目標方法是"+joinPoint.getSignature().getName());

    }
    /*3.環繞通知
    * ProceedingJoinPoint 是JoinPoint子介面,表示可執行的目標方法
    * 1. 必須是Object返回值
    * 2. 引數必須是ProceedingJoinPoint型別
    * 3.必須throws Throwable
     *
    *
    * */
    public Object myAround(@NonNull  ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("環繞開始:執行目標方法之前,模擬開啟事務‘。。。。");
        //執行當前的方法
        Object proceed = proceedingJoinPoint.proceed();

        System.out.println("環繞結束:執行目標方法之後,模擬關閉事務‘。。。。");
        return proceed;

    }
    /*4.異常通知*/
    public void myAfterThrowing( JoinPoint joinPoint, @NonNull  Throwable throwable){
        System.out.println("異常通知:出錯了"+ throwable.getMessage());

    }


    /*5.最終通知*/
 public  void myAfter(){
     System.out.println("模擬方法,釋放資源");
 }

}

4.ApplicationContext.xml

<?xml version="1.0" encoding="UTF8"?>
         <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:context="http://www.springframework.org/schema/context"
                xmlns:p="http://www.springframework.org/schema/p"
                xmlns:util="http://www.springframework.org/schema/util"
                xmlns="http://www.springframework.org/schema/beans"
                xmlns:aop="http://www.springframework.org/schema/aop"
              xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/aop
              http://www.springframework.org/schema/aop/spring-aop.xsd">
     <!--1.目標類-->
  <bean id="userDao" class="com.sty.dao.UserDaoImpl"/>


   <!--2.切面-->
<bean id="myAspect" class="com.sty.dao.aspect.MyAspect"/>

   <!--3.Aop程式設計-->
   <aop:config>
      <!--3.1配置切面-->
      <aop:aspect id="aspect" ref="myAspect">
      <!--3.2配置切點-->
       <aop:pointcut id="myPointCut" expression="execution(* com.sty.dao.UserDaoImpl.add(..))"/>
         <!--3.3配置通知-->
        <aop:before method="myBefore" pointcut-ref="myPointCut"/>
         <aop:around method="myAround" pointcut-ref="myPointCut"/>
         <aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="returnVal"/>
         <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="throwable"/>
         <aop:after method="myAfter" pointcut-ref="myPointCut"/>
      </aop:aspect>
   </aop:config>



</beans>

5.測試

public class MyTest2 {
    /*自定義切面*/
    @Test
    public void TestDiy() {
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");

           UserDao userDao = (UserDao) context.getBean("userDao");
            userDao.add();
        System.out.println("------------------");
            userDao.delete();

註解配置

1.UserDao

package com.sty.AnnotationDao;
import org.springframework.stereotype.Repository;
public interface UserDao {

    //新增使用者
     void add();

    //刪除使用者
    void delete();
}

2.UserDaoImpl.java

package com.sty.AnnotationDao;

import org.springframework.stereotype.Repository;

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    public void add() {
        System.out.println("增加一個使用者");
    }

    public void delete() {
        System.out.println("刪除一個使用者");
    }
}

3.myAspect.java

package com.sty.AnnotationDao.aspect;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;


/*
* 面向切面類
* */
@Component
@Aspect //定義一個切面
public class MyAspect {

    /*定義一個表示式*/
    @Pointcut("execution(* com.sty.AnnotationDao.*.*(..))")
    public void myPointCut(){}


    /*1.前置通知*/
    @Before("myPointCut()")
    public void myBefore(@NonNull JoinPoint  joinPoint){
        System.out.println("前置通知:模擬執行許可權。。。。。");
        System.out.println("目標類是:"+joinPoint.getTarget());
        System.out.println(","+"被植入增強處理的目標方法是"+joinPoint.getSignature().getName());
    }

    /*2.後置通知*/
    @After("myPointCut()")
    public void myAfterReturning(@NonNull JoinPoint joinPoint){
        System.out.println("後置通知:模擬記錄日誌");
        System.out.println("被植入增強處理的目標方法是"+joinPoint.getSignature().getName());

    }
    /*3.環繞通知
    * ProceedingJoinPoint 是JoinPoint子介面,表示可執行的目標方法
    * 1. 必須是Object返回值
    * 2. 引數必須是ProceedingJoinPoint型別
    * 3.必須throws Throwable
     *
    *
    * */
    @Around("myPointCut()")
    public Object myAround(@NonNull  ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("環繞開始:執行目標方法之前,模擬開啟事務‘。。。。");
        //執行當前的方法

        Object proceed = proceedingJoinPoint.proceed();

        System.out.println("環繞結束:執行目標方法之後,模擬關閉事務‘。。。。");
        return proceed;

    }
    /*4.異常通知*/
    @AfterThrowing(value = "myPointCut()",throwing = "throwable")
    public void myAfterThrowing( JoinPoint joinPoint, @NonNull  Throwable throwable){
        System.out.println("異常通知:出錯了"+ throwable.getMessage());

    }


    /*5.最終通知*/
    @After("myPointCut()")
 public  void myAfter(){
     System.out.println("模擬方法,釋放資源");
 }

}

4.application.xml

<?xml version="1.0" encoding="UTF8"?>
         <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:context="http://www.springframework.org/schema/context"
                xmlns:p="http://www.springframework.org/schema/p"
                xmlns:util="http://www.springframework.org/schema/util"
                xmlns="http://www.springframework.org/schema/beans"
                xmlns:aop="http://www.springframework.org/schema/aop"
              xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/aop
              http://www.springframework.org/schema/aop/spring-aop.xsd">






    <!--指定需要掃描的包-->
    <context:component-scan base-package="com.sty"/>

    <!--啟動基於註解的聲名式Aspect支援-->
    <aop:aspectj-autoproxy/>

</beans>