AOP:面向切面編程,其核心思想就是,將原本代碼中的公共業務進行抽取,如:日志、事務、權限驗證等;實現公共業務代碼的復用性,並且使特定業務的功能更純粹,關注點減少。
AOP的本質是通過動態代理實現,通過反射機制獲取動態代理對象,實現對公共業務的抽取。
這里簡單介紹一下AOP的一些專有名詞。
橫切關注點:就是一個功能,如:視圖、權限驗證、日志等,這里用權限驗證舉例;
切面(Aspect):實現權限驗證的類,(Auth類);
通知(Advice):實現類中的方法,如:Auth類中的authenticate()方法;
目標:業務類的接口,如:user的接口;
代理:代理類 ---> 動態代理生成;
連接點、切入點: Auth類中的authenticate()方法在什么位置執行。
使用切面實現接口的方式實現:
1. 定義service接口
package com.yd.service; public interface UserService { public void add(); public void delete(); public void update(); public void query(); }
2. 編寫service接口實現類
package com.yd.service; public class UserServiceImpl implements UserService { public void add() { System.out.println("add"); } public void delete() { System.out.println("delete"); } public void update() { System.out.println("update"); } public void query() { System.out.println("query"); } }
3. 編寫切面實現接口
package com.yd.log; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class Log implements MethodBeforeAdvice { public void log() { System.out.println("log"); } public void before(Method method, Object[] args, Object target) throws Throwable { /** * method: 被增強的方法 * args: 被增強方法的參數列表 * target: 被增強的方法所屬類的對象 */ log(); } }
org.springframework.aop.AfterAdvice ----> 方法執行后的增強
org.springframework.aop.AfterReturningAdvice ----> 帶有返回值的方法執行后的增強,方法默認返回值為null
org.springframework.aop.MethodBeforeAdvice -----> 方法執行之前的增強
4. 配置spring.xml文件
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="com.yd.service.UserServiceImpl"/> <bean id="log" class="com.yd.log.Log"/> <!--配置aop--> <aop:config> <!--配置切入點--> <aop:pointcut id="pointcut" expression="execution(* com.yd.service.UserServiceImpl.*(..))"/> <!--配置環繞增強--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> </aop:config> </beans>
5. 編寫測試類
import com.yd.service.UserService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { @Test public void test() { // 創建上下文對象 ApplicationContext context = new ClassPathXmlApplicationContext("application.xml"); // 獲取bean對象並強轉成接口對象,因為動態代理是代理接口創建代理類的 UserService userService = (UserService) context.getBean("userService"); userService.add(); } }