javascript
Spring_02_AOP初级总结
?1.AOP簡介
是對OOP編程方式的一種補充。翻譯過來為“面向切面編程”。
可以理解為一個攔截器框架,但是這個攔截器會非常武斷,如果它攔截一個類,那么它就會攔截這個類中的所有方法。如對一個目標列的代理,增強了目標類的所有方法。
兩個解決辦法:
1.不優雅的做法:
在添加增強時,根據方法名去判斷,是否添加增強,但是這樣就得一直去維護這個增強類。
2.面向切面:
將增強類和攔截條件組合在一起,然后將這個切面配置到 ProxyFactory 中,從而生成代理。
二、AOP 和 切面的關系
1.類比于 OOP 和 對象,AOP 和 切面就是這樣的一種關系。
2.也可以將 切面 看成是 AOP 的一個工具。
三、幾個概念
切面(Advisor):是AOP中的一個術語,表示從業務邏輯中分離出來的橫切邏輯,比如性能監控,日志記錄,權限控制等。
這些功能都可以從核心的業務邏輯中抽離出去??梢越鉀Q代碼耦合問題,職責更加單一。封裝了增強和切點。
增強(Advice):增強代碼的功能的類,橫切到代碼中。
目標:目標方法(JDK代理)或目標類(CGLIB代理)
代理:JDK代理,CGLIB代理。或是通過 ProxyFactory 類生產。
切點:通過一個條件來匹配要攔截的類,這個條件稱為切點。如攔截所有帶 Controller 注解的類。增強的條件。
連接點:作為增強方法的入參,可以獲取到目標方法的信息。
四、概括為一張圖
五、增強
1.Weaving(織入):對方法進行增強
(1)前置增強(BeforeAdvice):在目標方法前調用。
(2)后置增強(AfterAdvice):在目標方法后調用。
(3)環繞增強(AroundAdvice):將 Before 和 After ,甚至拋出增強和返回增強合到一起。
(4)返回增強(AfterReturningAdvice):在方法返回結果后執行,該增強可以接收到目標方法返回結果。
(5)拋出增強(AfterThrowingAdvice):在目標方法拋出對應的類型后執行,可以接收到對應的異常信息。
2.Introduction(引入):對類進行增強
(1)引入增強(DeclareParentsAdvice):想讓程序在運行的時候動態去實現某個接口,需要引入增強。
2.代碼實現?
2.1?AOP的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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"><!-- xmlns:aop="http://www.springframework.org/schema/aop" 聲明要用aop的標簽xsi:schemaLocation= aop的標簽地址"http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" --><bean id="studentDao" class="org.jsoft.dao.impl.StudentDaoImpl"></bean><bean id="studentDaoByMybatis" lazy-init="true"class="org.jsoft.dao.impl.StudentDaoByMybatisImpl"></bean><bean id="studentService" class="org.jsoft.service.impl.StudentServiceImpl"scope="singleton" autowire="byName"></bean><!-- AOP面向切面的配置 --><!-- 切面對應的類,即切面類 --><bean id="log" class="org.jsoft.log.Log" /> <!-- --> <!-- --><aop:config><aop:aspect id="myAspect" ref="log"><!-- 切面標簽,id標記名稱,ref對應的切面類bean的id --><!-- 切點標簽,id標記名稱 --><aop:pointcut id="businessService"expression="execution(* org.jsoft.service..*.*(..))" /><!-- 在該范圍的類的所有方法下,執行AOP方法 --><!-- 程序執行前,要執行的方法"before" --><aop:before pointcut-ref="businessService" method="before"/><!-- --><!-- 程序執行后,要執行的方法"after" --> <aop:after pointcut-ref="businessService" method="after"/><!-- 程序整個過程,要執行的方法"around" --><aop:around pointcut-ref="businessService"method="around" /></aop:aspect></aop:config></beans>2.2 對應切面類Log
package org.jsoft.log;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;import org.aspectj.lang.ProceedingJoinPoint; //這是一個切面類,已放入IoC容器里. public class Log implements InvocationHandler{private Object obj;public void before(){//(1)前置增強,需要實現:MethodBeforeAdvice 接口System.out.println("Log.before()");}public void after(){//(2)后置增強:實現 AfterReturningAdvice 接口System.out.println("Log.after()");}//(3)環繞增強:實現 org.aopalliance.intercept.MethodInterceptor 接口,//使用 Object result = methodInvocation.proceed(); 調用目標方法。在目標方法前后添加增強public Object around(ProceedingJoinPoint pjp) throws Throwable{long l = System.currentTimeMillis();Object retVal = pjp.proceed();//new Thread().sleep(100);System.out.println(System.currentTimeMillis() - l);System.out.println("Log.around()");return retVal;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {before();Object result = method.invoke(obj, args);after();return result;}public Object getObj() {return obj;}public void setObj(Object obj) {this.obj = obj;} }2.3 main測試
import org.springframework.context.support.ClassPathXmlApplicationContext;/**ApplicationContext 是接口,下面的ClassPathXmlApplicationContext也可以用,后者可以用.close()方法*/ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"spring/spring.xml"}); Student s = new Student(); s.setName("Joy"); Log log = new Log(); log.setObj(studentService); //動態代理 //參數1 classLoader類加載器 //interfaces造出來的類要實現那些接口 IStudentService studentServiceProxy = (IStudentService)Proxy.newProxyInstance(Main.class.getClassLoader(), studentService.getClass().getInterfaces(), log);studentServiceProxy.add(s); context.close();?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Spring_02_AOP初级总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ps突出字体怎么设计(ps突出字体怎么设
- 下一篇: 微信JS-SDK实现分享功能