Spring------AOP,
一、概念?
AOP是Aspect Oriented Programming的縮寫,意思為面向切面編程。它最大的作用,那就是為瞭解決程式功能擴充的問題,而且在增強 期間不需要改動原代碼。底層運用動態代理模式實現。
動態代理的實現有兩種,而核心其實就是多態。無論是基於JDK的動態代理還是基於cglib的動態代理,只不過一個是利用介面和實作類別的關係,一個是利用父類和子類的關係。
這種動態代理應用的特點為:如果哪一個真實類有實現介面,那麼就採用這種方式,建立出來介面的另一個實作類別作為代理類。它是利用介面和實作類別的關係,建立一個實現共同介面的代理類。
- 基於cglib的動態代理:如果真實類是一個普通類,沒有實現介面,那麼就採用這種方式, 建立出來真實類的子類作為代理類。
通過例子來體會
@Test //基於JDK代理 public void fun01() { //建立真實對象 final UserService userService = new UserServiceImp(); //擷取真實對象的載入器、介面,建立一個代理類 //反射調用方法 UserService proxyInstance = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /* * proxy : 代理對象,幾乎不用 * method: 方法的引用 save() --- save方法的引用 * args: 方法參數 */ if ("saveUser".equals(method.getName())) { Logger.logger(); } ////反射調用 把結果跑出去,讓代理對象也能收到結果。 return method.invoke(userService, args); // return null; } }); //代理並不會幹活,真正幹活的是真實類 proxyInstance.saveUser(); }
@Test //基於Cglib動態代理 //如果真實類是一個普通類,沒有實現介面,那麼就採用這種方式, 建立出來真實類的子類作為代理類。 public void fun02() { //啟用建立執行者 Enhancer enhancer = new Enhancer(); //建立真實對象 final UserService2 userService = new UserService2(); enhancer.setSuperclass(UserService2.class); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { Logger.logger(); return method.invoke(userService, objects); } }); UserService2 proxyInstance = (UserService2) enhancer.create(); proxyInstance.test(); }二、AOP術語
三、AOP入門
public class UserServiceImpl implements UserService { @Override public void save() { System.out.println("調用了UserServiceImpl 的 save方法"); }}
- 定義增強類
public class Logger { public static void log(){ System.out.println("輸出日誌了~~"); }}
- 匯入jar包
a. 匯入 spring必須的jar b. 額外匯入: spring-aop-xx.jar,spring-aspect-xx.jar 面向切面過程中,Spring AOP是遵循了AOP同盟規範實現的,所以需要有AOP同盟介面包 aopalliance-x.x.jar,介面包依賴aspectjweaver-x.x.x.jar
- xml配置
<?xml version="1.0" encoding="UTF-8"?><!--aop入門配置--><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" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="gaga"/> <bean id="us" class="gaga.service.serviceimp.UserServiceImp"/> <bean id="ul" class="gaga.utils.Logger"/> <aop:config> <aop:pointcut id="a" expression="execution(* gaga.service.serviceimp.*.*(..))"/> <aop:aspect ref="ul"> <aop:after method="logger" pointcut-ref="a"/> </aop:aspect> </aop:config></beans>