spring學習路線:day04--面向切面編程(aop詳解)

一:Aop簡介

  1. aop:aspect oriented programming 面向切面編程

  2. aop在spring中作用

    提供聲明式服務(聲明式事務)
    允許用戶實現自定義切面
    spring aop就是將公共的業務(如日誌,安全等)和領域業務結合。當執行領域業務時將會把公共業務加進來。實現公共業務的重複利用。領域業務更純粹。程序猿專注於領域業務。其本質還是動態代理。

  3. aop編程與傳統編程模式比較
    傳統編程模式:
    在這裏插入圖片描述
    aop編程模式:橫向的編程,在不改變原來的代碼下增加新的功能
    在這裏插入圖片描述

  4. aop的好處:

    • 使得真實角色處理的業務更加純粹,不再去關注一些公共的事情。
    • 公共的業務由代理來完成–實現業務的分工
    • 公共業務發生擴展時變得更加集中和方便
      5.名詞解釋
      關注點:增加的某個業務。如日誌,安全,緩存,事務等。
      切面(Aspect):一個關注點的模塊化。例如把一個方法封裝成一個類。
      通知(Advice):在切面的某個特定的連接點(方法)上執行的動作。
      織入(Weaving):把切面連接到其他的應用程序類型或者對象上,並創建一個被通知的對象。
  5. aop就是把一類的功能封裝起來,通過切面的方式加入到其它業務中

二:使用spring實現aop

1.通過springAPI實現

Log–前置通知:

public class Log implements MethodBeforeAdvice{
    /**前置通知:目標方法執行前執行的通知
     * method 被調用的方法對象
     * args 被調用的方法的參數
     * target 被調用方法的目標對象
     */
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println(arg2.getClass().getName()+"的"+arg0.getName()+"方法被調用");
		
	}
   
}

AfterLog–後置通知

public class Log implements MethodBeforeAdvice{
    /**前置通知:目標方法執行前執行的通知
     * method 被調用的方法對象
     * args 被調用的方法的參數
     * target 被調用方法的目標對象
     */
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println(arg2.getClass().getName()+"的"+arg0.getName()+"方法被調用");
		
	}
   
}

實現類UserServiceImpl:

public class UserServiceImpl implements UserService{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("增加用戶");
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		System.out.println("更新用戶");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("刪除用戶");
	}

	@Override
	public void search() {
		// TODO Auto-generated method stub
		System.out.println("查找用戶");
	}

}

配置文件beans:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c"
    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/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="userService" class="net.xyz.service.UserServiceImpl"></bean>
    <bean id="log" class="net.xyz.log.Log"></bean>
    <bean id="afterLog" class="net.xyz.log.AfterLog"></bean>
    <aop:config>
       <!-- 配置指定類下的所有方法,並能涵蓋所有參數 -->
        <aop:pointcut expression="execution(* net.xyz.service.UserServiceImpl.*(..))" id="pointcut"/>
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>
</beans>

測試類:

public class Text {
	public static void main(String[] args) {
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
		UserService userService =(UserService) ac.getBean("userService");
		userService.add();
		userService.delete();
	}

}

2.自定義類實現aop

log.java

public class Log {
  public void before() {
	  System.out.println("----在方法之前執行--------");
  }
  public void after() {
	  System.out.println("----在方法之後執行-------");
  }
}

UserServiceImpl:

public class UserServiceImpl implements UserService{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("增加用戶");
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		System.out.println("更新用戶");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("刪除用戶");
	}

	@Override
	public void search() {
		// TODO Auto-generated method stub
		System.out.println("查找用戶");
	}

}

配置文件:

public class UserServiceImpl implements UserService{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("增加用戶");
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		System.out.println("更新用戶");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("刪除用戶");
	}

	@Override
	public void search() {
		// TODO Auto-generated method stub
		System.out.println("查找用戶");
	}

}

控制檯顯示:
在這裏插入圖片描述

3.通過註解方式實現aop

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c"
    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/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="userService" class="net.xyz.service.UserServiceImpl"></bean>
    <bean id="log" class="net.xyz.log.Log"></bean>
     <aop:aspectj-autoproxy>
     </aop:aspectj-autoproxy>
</beans>

log.java

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.MethodBeforeAdvice;
@Aspect
public class Log {
  @Before("execution(* net.xyz.service.UserServiceImpl.*(..))")//方法前執行
  public void before() {
	  System.out.println("----在方法之前執行--------");
  }
  @After("execution(* net.xyz.service.UserServiceImpl.*(..))")//方法後執行
  public void after() {
	  System.out.println("----在方法之後執行-------");
  }
  @Around("execution(* net.xyz.service.UserServiceImpl.*(..))")//環繞通知,方法前後都會執行
  public Object around(ProceedingJoinPoint jp) throws Throwable {
	  System.out.println("環繞前");
	  System.out.println("簽名:"+jp.getSignature());
	  //執行目標方法
	  Object result =jp.proceed();
	  System.out.println("環繞後");
	  return result;
  }
}

Text類:

public class Text {
	public static void main(String[] args) {
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
		UserService userService =(UserService) ac.getBean("userService");
		userService.add();
	}

}

控制檯:
在這裏插入圖片描述
最後:文章中出現的任何資源都可以私聊我要喲,就不要上傳資源了,很麻煩。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章