springAOP

springAOPjava

1、IOC

IOC叫控制反轉,對象的建立由外部框架來實現,控制權交給了外部容器,控制發生了反轉,也叫依賴注入,程序中須要對象,則依賴外部框架把對象進行注入。IOC是一個容器,對象被建立以後都存儲在這個容器中,對象默認是單例模式,能夠經過scope這個屬性來改變。對象的配置能夠在配置文件中處理,也能夠運用註解的方式來建立對象,程序經過ApplicationContext.getBean()這個方法來獲取對象,也能夠經過註解@Autowired@Resource(name="stu12")自動注入。若是是經過註解的方式來自動建立Bean,則配置文件要啓動註解並掃描相關的包,類前還須要添加相關的註解: @Service@Component@Controller@Repositoryspring

2、AOP

面向切面編程,對於程序內部進行橫切關注,把公共的代碼抽取出來,造成切面,再經過鏈接點去監聽指定方法的執行狀況,在方法執行過程當中把切面織入到被監聽的方法中去。方法被動的被執行某些功能代碼。express

3、相關概念:

Aspect(切面):指橫切性關注點的抽象即爲切面,它與類類似,只是二者的關注點不同,類是對物體特徵的抽象,而切面是橫切性關注點的抽象.編程

 

joinpoint(鏈接點):所謂鏈接點是指那些被攔截到的點。在spring,這些點指的是方法,由於spring只支持方法類型的鏈接點,實際上joinpoint還能夠是field或類構造器)app

 

Pointcut(切入點):所謂切入點是指咱們要對那些joinpoint進行攔截的定義.框架

 

Advice(通知):所謂通知是指攔截到joinpoint以後所要作的事情就是通知.通知分爲前置通知,後置通知,異常通知,最終通知,環繞通知spa

 

Target(目標對象):代理的目標對象代理

 

Weave(織入):指將aspects應用到target對象並致使proxy對象建立的過程稱爲織入.component

 

Introduction(引入):在不修改類代碼的前提下, Introduction能夠在運行期爲類動態地添加一些方法或Field.xml

 

4、AOP運用

  1. 添加相關的jar

aopalliance-1.0.0.jar

aspectjweaver-1.6.8.jar

commons-logging-1.1.1.jar

spring-aop-4.3.10.RELEASE.jar

spring-aspects-4.3.10.RELEASE.jar

spring-beans-4.3.10.RELEASE.jar

spring-context-4.3.10.RELEASE.jar

spring-core-4.3.10.RELEASE.jar

spring-expression-4.3.10.RELEASE.jar

 

  1. 把方法的公共抽取出來造成切面類及通知

@Component  //掃描到IOC容器中去

@Aspect  //表示這個類是一個切面類

public class LogInfo {

/* execution(public springAOP0305.Calc.*(int, int))切面表達式,指定要監聽的方法

 *  springAOP0305.Calc.* 是一個通配符,任何方法都行,int,int是方法的參數,必須是兩個int型才監聽。

 *  能夠改爲.. 表示任意類型,任意數量的參數都行

 */

//前置通知,在監聽的方法執行前執行..

@Before("execution(* springAOP0305.*.*(..))")

public void before() {

System.out.println("方法開始執行.......... ");

}

 

//後置通知,在方法正確執行完畢,返回結果以前執行。

@After("execution(* springAOP0305.*.*(..))")

public void after() {

System.out.println("方法執行結束...");

}

}

 

  1. 添加配置文件的配置,掃描切面類及其餘的類到IOC容器中

xmlns:aop="http://www.springframework.org/schema/aop" 

xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.0.xsd

">

  <!-- 啓用註解配置,-->

  <context:annotation-config/>

  <!-- 掃描包中的類,把有註解的類自動建立出對象,存儲在IOC容器中  -->

  <context:component-scan base-package="springAOP0305"/>

  <!-- 啓動AOP的代理 -->

  <aop:aspectj-autoproxy proxy-target-class="true"/>

</beans>

 

  1. 調用被監聽的方法

public static void main(String[] args) {

 ApplicationContext cxt = new ClassPathXmlApplicationContext("config/applicationcontext.xml");

 Calc c = cxt.getBean(Calc.class);

 int result = c.add(100, 50, 20);

 System.out.println("計算結果是:"+result);

}

  1. 結果

 

通知:

/*

 * execution(public springAOP0305.Calc.*(int, int))切面表達式,指定要監聽的方法

 * springAOP0305.Calc.* 是一個通配符,任何方法都行,int,int是方法的參數,必須是兩個int型才監聽。 能夠改爲..

 * 表示任意類型,任意數量的參數都行

 */

// 前置通知,在監聽的方法執行前執行..

@Before("execution(* springAOP0305.*.*(..))")

public void before(JoinPoint jp) {

// JoinPoint 是一個鏈接點對象,封裝了方法名稱及參數,jp.getSignature().getName()方法名稱

String name = jp.getSignature().getName();

Object[] args = jp.getArgs(); // 取鏈接點的參數列表

System.out.println(name + "方法: 開始執行,參數是:" + Arrays.toString(args));

}

 

// 後置通知,在方法正確執行完畢,返回結果以前執行,不能獲取方法的返回結果。

@After("execution(* springAOP0305.*.*(..))")

public void after(JoinPoint jp) {

// JoinPoint 是一個鏈接點對象,封裝了方法名稱及參數,jp.getSignature().getName()方法名稱

String name = jp.getSignature().getName();

Object[] args = jp.getArgs(); // 取鏈接點的參數列表

System.out.println(name + "方法: 執行結束了,參數是:" + Arrays.toString(args));

}

 

/*

 * 返回通知,也叫最終通知,在方法返回結果時執行,此時能夠獲取到方法返回的結果

 * value表示切面表達式,

 * returning:表示方法返回的結果封裝的參數名稱

 */

@AfterReturning(value = "execution(* springAOP0305.*.*(..))", returning = "result")

public void afterReturn(JoinPoint jp, Object result) {

// JoinPoint 是一個鏈接點對象,封裝了方法名稱及參數,jp.getSignature().getName()方法名稱

String name = jp.getSignature().getName();

Object[] args = jp.getArgs(); // 取鏈接點的參數列表

System.out.println(name + "方法: 正確返回結果,參數是:" + Arrays.toString(args)+",計算結果是:"+result);

}

//異常通知,也叫例外通知,在方法執行中出現異常才執行,不然不執行,若是有異常,則返回通知不會執行

@AfterThrowing("execution(* springAOP0305.*.*(..))")

public void afterThrow() {

System.out.println("發生錯誤..");

}

當有多個切面的時候,能夠給切面執行順序進行設置,在切面類前添加註解@Order(value=1), 值越小,優先級越高。

@Aspect

@Component

@Order(value=1)  //順序設置,值小的優先級高

public class TimeInfo {

@Before("execution(* springAOP0305.*.*(..))")

public void befor() {

System.out.println("時間開始記錄..");

}

}

 

5、XML配置

在開發中大部分仍是採用註解的方式來進行配置,事務管理機制,採用的就是註解配置,簡單。

 <!-- 切面類的對象 -->

  <bean id="logInfo" class="springAOP0305.LogInfo"/>

  <bean id="timeInfo" class="springAOP0305.TimeInfo"/>

  

  <!-- AOP配置 -->

  <aop:config>

    <!-- 切入點:切點表達式, -->

    <aop:pointcut expression="execution(* springAOP0305.*.*(..))" id="pcut"/>

    <!-- 切面及通知的配置 order:切面織入的順序 -->

    <aop:aspect ref="timeInfo" order="1">

      <aop:before method="befor" pointcut-ref="pcut"/>

    </aop:aspect>

    <aop:aspect ref="logInfo" order="2">

      <aop:before method="before" pointcut-ref="pcut"/>

      <aop:after method="after" pointcut-ref="pcut"/>

    </aop:aspect>

  </aop:config>

6、通配符:

expression-匹配方法執行的鏈接點,是Spring最主要的切入點

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

除了返回類型模式(),名字模式和參數模式之外,其他的都是可選的,*爲任意通配符

expression=execution(* cn.itcast.service..*.*(..))」表示做用在cn.itcast.service包及子包下全部的類的全部方法上

expression=execution(* cn.itcast.service..*.*(java.lang.String,..))」表示做用在cn.itcast.service包及子包下全部的類的第一個參數爲String類型的方法上

expression=execution(java.lang.String cn.itcast.service..*.*(..))」 表示做用在cn.itcast.service包及子包下全部的類的返回值類型爲String的方法上

expression=execution(!java.lang.String cn.itcast.service..*.*(..))」 表示做用在cn.itcast.service包及子包下全部的類的返回值類型不是String的全部方法上

expression=execution(* set**(..))」 表示做用在任意以set開始的方法上

within-限定匹配特定類型的鏈接點

expression=winthin(cn.itcast.*)」 表示做用在cn.itcast包及子包下的全部鏈接點

相關文章
相關標籤/搜索