1.什麼是面向切面編程?
springAop是面向切面編程的一種代表,通過對多模塊下共同功能的統一管理,來控制業務邏輯與公有邏輯的解耦,而散佈於應用多處共有的功能稱爲橫切關注點,把這些橫切關注點與業務邏輯相分離是面向切面編程需要解決的問題。
下面介紹通過xml文件的方式來實現springaop簡單應用:
2.springaop應用
實現方式一,使用xml完成定義切面的功能:
第一步,搭建項目環境,工程目錄圖如下:
添加依賴,spring-context包,aspectj包:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.8</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.3</version>
</dependency>
第二步: 新建一個接口
package com.hand.proxy.aop;
public interface EatInter {
void eat();
}
並去實現它:
package com.hand.proxy.aop;
public class People implements EatInter {
public void eat() {
System.out.println("喫飯!");
}
}
第三步,創建切面類
package com.hand.proxy.aop;
public class DoSomethingHelp {
/**
* 切面類,指定公有的方執行的一些動作
*/
public void eatPoint() {
System.out.println("切點");
}
public void beforeEat() {
System.out.println("喫飯之前,我們應該去洗手!");
}
public void afterEat() {
System.out.println("喫飯後,去睡覺!");
}
}
第四步,添加applicationContext.xml文件,配置切面類和bean,通過xml文件的 方式來配置切面和通知類型:
其中創建的切點時,指定連接點,此處把接口中的eat()方法來作爲連接點。
<aop:config> 標籤用來配置aop
<aop:aspectj> 標籤用來指定切面,其中ref屬性就是用來引用切面類。
<aop:before> 和<aop:after> 標籤表示通知的類型
<?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"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean id="people" class="com.hand.proxy.aop.People" ></bean>
<bean id='aspectJ' class="com.hand.proxy.aop.DoSomethingHelp"></bean>
<!-- 需要添加此配置,將需要代理的類織入到切面中 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<aop:config>
<aop:aspect ref="aspectJ">
<aop:after method="afterEat" pointcut="execution(* com.hand.proxy.aop.EatInter.eat(..))"/>
<aop:before method="beforeEat" pointcut="execution(* com.hand.proxy.aop.EatInter.eat(..))"></aop:before>
</aop:aspect>
</aop:config>
</beans>
注:如果此處不添加如下標籤 :
<aop:aspectj-autoproxy proxy-target-class="true"/>
會報錯:
org.springframework.beans.factory.BeanNotOfRequiredTypeException:
Bean named 'people' is expected to be of type 'com.hand.proxy.aop.People' but was actually of type 'com.sun.proxy.$Proxy6'
原因是:需要通過此配置將切點織入到目標的切面類中,默認的proxy-target-class爲false。
測試案例:
package com.hand.proxy.aop;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopTest {
@Test
public void testAop(){
ApplicationContext ac
=new ClassPathXmlApplicationContext("applicationContext.xml");
People people=ac.getBean("people",People.class);
people.eat();
}
}
打印結果如下:
喫飯之前,我們應該去洗手!
喫飯!
喫飯後,去睡覺!
實現方式二: 使用註解來定義切面