A:spring AOP--代理對象[主要用於許可權控制]
1:Proxy代理,前提在於代理對象必須實現介面 sina部落格上
2:如果未實現介面 /lib/cglib/cglib-nodep-2.1_3.jar sina部落格上[spring的實現方式實現介面jdk,未實現介面cglib]
3:(Advice)通知,前置,後置,例外,最終,環繞
(Aspect)切面,對橫切向關注點的一個抽象。幾乎就是個類
joinpoint(連接點) spring中一般指方法,傳統的還有構造方法,欄位等
targetObject
Weave(織入) 將切面應用到目標對象並導致proxy對象建立的過程
Introduction(引入)在不修改類代碼的前提下,Introduction可以在運行時為類動態添加一些方法或欄位
B:spring aop開發兩種方式
1:基於註解方式進行AOP開發(所要用到的jar檔案,見上一篇spring2.5註解基礎)
package test;<br />import org.springframework.stereotype.Component;</p><p>@Component("helloworld")<br />public class HelloWorld {</p><p> public void sayHello(String helloworld) {<br /> System.out.println(helloworld);<br />// throw new RuntimeException();<br /> //這個異常是拿來測試,可有可無<br /> }<br /> public void say() {<br /> System.out.println("測試");<br />// throw new RuntimeException();<br /> //這個異常是拿來測試,可有可無<br /> }<br /> public String getSay() {<br /> return "測試";<br />// throw new RuntimeException();<br /> //這個異常是拿來測試,可有可無<br /> }<br />}</p><p>
package test;<br />import org.aspectj.lang.ProceedingJoinPoint;<br />import org.aspectj.lang.annotation.After;<br />import org.aspectj.lang.annotation.AfterReturning;<br />import org.aspectj.lang.annotation.AfterThrowing;<br />import org.aspectj.lang.annotation.Around;<br />import org.aspectj.lang.annotation.Aspect;<br />import org.aspectj.lang.annotation.Before;<br />import org.aspectj.lang.annotation.Pointcut;<br />import org.springframework.stereotype.Component;</p><p>@Component<br />@Aspect //指定一個切面<br />public class AspectS {</p><p> // execution最常用,可以通過 & || !進行切入點運算式的串連<br /> // 可是是運算式,可以通過切入點標識重用運算式<br /> //聲明一個切入點第一個*號傳回型別,test後面..代表包及下面子包【不寫就只代表當前包】,*所有方法,(..)方法的參數<br /> @Pointcut("execution(* test..*(..))")<br /> public void helloworld() {<br /> }</p><p>// @Before("execution(public void test.HelloWorld.sayHello(String))")<br />// public void beforeSayHello() {<br />// System.out.println("before sayHello");<br />// }<br />//前置通知<br />//表示只攔截到滿足上面切入點的以及帶有一個參數的方法 args裡面的參數跟方法帶的參數名稱一致<br />// @Before("helloworld()&&args(name)")<br />// public void beforeSayHello(String name) {<br />// System.out.println("before sayHello:::::::"+name);<br />// }</p><p>//攔截到所有方法<br />// @Before("helloworld()")<br />// public void beforeSayHello() {<br />// System.out.println("before sayHello:::::::");<br />// }</p><p> //最終通知<br />// @After("helloworld()")<br />// public void afterSayHello() {<br />// System.out.println("after sayHello");<br />// }<br />//例外通知<br />// @AfterThrowing("test.AspectS.helloworld()")<br />// public void exceptionSayHello() {<br />// System.out.println("throw runtime exception");<br />// }<br /> //擷取方法拋出的異常<br /> //例外通知<br /> @AfterThrowing(pointcut="helloworld()",throwing="e")<br /> public void exceptionSayHello(Exception e) {<br /> System.out.println("throw runtime exception"+e);<br /> }<br />//後置通知<br />// @AfterReturning("test.AspectS.helloworld()")<br />// public void returnSayHello() {<br />// System.out.println("method has returned");<br />// }<br /> //得到方法的返回結果<br />// @AfterReturning(pointcut="helloworld()",returning="result")<br />// public void returnSayHello(String result) {<br />// System.out.println("method has returned"+result);<br />// }</p><p>//環繞通知<br />// @Around("test.AspectS.helloworld()")<br />// public Object aroundSayHello(ProceedingJoinPoint pjp) {<br />// Object obj = null;<br />// try {<br />// System.out.println("around start");<br />// obj = pjp.proceed();<br />// System.out.println("around end");<br />// } catch (Throwable e) {<br />// e.printStackTrace();<br />// }<br />// return obj;<br />// }</p><p>}</p><p>
import org.springframework.context.ApplicationContext;<br />import org.springframework.context.support.ClassPathXmlApplicationContext;</p><p>import test.HelloWorld;</p><p>public class Client {</p><p> public static void main(String[] args) {<br /> ApplicationContext cx = new ClassPathXmlApplicationContext(<br /> "applicationContext.xml");<br /> HelloWorld bean = (HelloWorld)cx.getBean("helloworld");<br /> bean.sayHello("hello world");<br /> bean.say();<br /> bean.getSay();<br /> }<br />}</p><p>
設定檔(applicationContext.xml)
<?xml version="1.0" encoding="UTF-8"?><br /><beans xmlns="http://www.springframework.org/schema/beans"<br /> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"<br /> xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"<br /> xsi:schemaLocation=" </p><p>http://www.springframework.org/schema/beans</p><p>http://www.springframework.org/schema/beans/spring-beans-2.5.xsd</p><p>http://www.springframework.org/schema/context</p><p>http://www.springframework.org/schema/context/spring-context-2.5.xsd</p><p>http://www.springframework.org/schema/aop</p><p>http://www.springframework.org/schema/aop/spring-aop-2.5.xsd</p><p>http://www.springframework.org/schema/tx</p><p> http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"></p><p> <context:annotation-config /><!--spring中bean用的是XML設定檔,而裝配時用註解的形式...註解:@Autowired(預設按類型進行裝配)轉變成按名稱尋找<br /> @Autowired【(required=true) ,加上此句,如果沒能注入則會拋出個例外】 @Qualifier("pro"),@Resource(name="pro")<br /> (預設按名稱,找不到再按類型,如果沒標記name則按照屬性去找)--><br /> <context:component-scan base-package="test" /><!-- spring自動掃描和管理bean的聲明,有了此處的聲明可以省去上一行 --><br /> <aop:aspectj-autoproxy /><!--切面編程的聲明--><br /></beans><br />