Java的Spring框架下的AOP編程形式示例。本站提示廣大學習愛好者:(Java的Spring框架下的AOP編程形式示例)文章只能為提供參考,不一定能成為您想要的結果。以下是Java的Spring框架下的AOP編程形式示例正文
Spring框架的症結組件是面向方面編程(AOP)框架。面向方面的編程不只打破法式邏輯分紅分歧的部門稱為所謂的擔心。逾越多個點的運用法式的功效被稱為橫切存眷點和這些橫切存眷點是從運用法式的營業邏輯概念上辨別開來。還有像日記記載,審計,聲明性事務,平安性和高速緩存等方面的各類罕見的好例子
模塊化的OOP中的症結單位是類,而在AOP中模塊化的單位則是切面。依附注入可以贊助你從對方解耦運用法式對象和AOP可以贊助你從他們影響的對象分別橫切存眷點。 AOP是一樣的編程說話如Perl,.NET,Java和其他觸發器。
Spring AOP模塊供給了攔阻器攔阻的運用法式,例如,履行一個辦法時,可以之前或以後履行的辦法添加額定的功效。
AOP術語:
在我們開端應用AOP之前,先熟習AOP的概念和術語。這些條目是不特定於Spring,成績都是有關AOP。
建議的類型
Spring方面可以用5種上面提到的建議:
自界說方面完成
Spring基於XML形式的AOP
須要以下所述導入Spring AOP架構:
<?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/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!-- bean definition & AOP specific configuration --> </beans>
還須要在以下運用法式CLASSPATH中的AspectJ庫。這些庫可以在AspectJ的裝置'lib'目次可用,可以從互聯網高低載它們。
聲明一個切面
一個方面是應用<aop:aspect>元素中聲明,而且支撐bean是應用ref屬性以下參考:
<aop:config> <aop:aspect id="myAspect" ref="aBean"> ... </aop:aspect> </aop:config> <bean id="aBean" class="..."> ... </bean>
這裡的“aBean”將設置裝備擺設和依附注入,就像任何其他的Spring bean,我們曾經在後面的章節看到。
聲明一個切入點
一個切入點有助於肯定與分歧要履行的銜接點的利錢(即辦法)。同時與XML架構基本的設置裝備擺設任務,切入點將被界說以下:
<aop:config> <aop:aspect id="myAspect" ref="aBean"> <aop:pointcut id="businessService" expression="execution(* com.xyz.myapp.service.*.*(..))"/> ... </aop:aspect> </aop:config> <bean id="aBean" class="..."> ... </bean>
上面的示例界說一個名為'的businessService“切入點將婚配可用的軟件包com.yiibai下履行getName()辦法在Student類:
<aop:config> <aop:aspect id="myAspect" ref="aBean"> <aop:pointcut id="businessService" expression="execution(* com.yiibai.Student.getName(..))"/> ... </aop:aspect> </aop:config> <bean id="aBean" class="..."> ... </bean>
聲明建議
可以聲明隨意率性五個建議的應用<aop:{ADVICE NAME}>元素上面給出一個<aop:aspect>內:
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
<aop:pointcut id="businessService"
expression="execution(* com.xyz.myapp.service.*.*(..))"/>
<!-- a before advice definition -->
<aop:before pointcut-ref="businessService"
method="doRequiredTask"/>
<!-- an after advice definition -->
<aop:after pointcut-ref="businessService"
method="doRequiredTask"/>
<!-- an after-returning advice definition -->
<!--The doRequiredTask method must have parameter named retVal -->
<aop:after-returning pointcut-ref="businessService"
returning="retVal"
method="doRequiredTask"/>
<!-- an after-throwing advice definition -->
<!--The doRequiredTask method must have parameter named ex -->
<aop:after-throwing pointcut-ref="businessService"
throwing="ex"
method="doRequiredTask"/>
<!-- an around advice definition -->
<aop:around pointcut-ref="businessService"
method="doRequiredTask"/>
...
</aop:aspect>
</aop:config>
<bean id="aBean" class="...">
...
</bean>
可使用雷同的doRequiredTask或分歧的辦法針對分歧的建議。這些辦法將被界說為縱橫模塊的一部門。
基於XML形式的AOP例
要懂得上述關系到XML形式的AOP提到的概念,讓我們寫這將完成幾個建議的一個例子。
這裡是Logging.java文件的內容。這現實上是縱橫模塊的一個示例,它界說的辦法被挪用的各個點。
package com.yiibai;
public class Logging {
/**
* This is the method which I would like to execute
* before a selected method execution.
*/
public void beforeAdvice(){
System.out.println("Going to setup student profile.");
}
/**
* This is the method which I would like to execute
* after a selected method execution.
*/
public void afterAdvice(){
System.out.println("Student profile has been setup.");
}
/**
* This is the method which I would like to execute
* when any method returns.
*/
public void afterReturningAdvice(Object retVal){
System.out.println("Returning:" + retVal.toString() );
}
/**
* This is the method which I would like to execute
* if there is an exception raised.
*/
public void AfterThrowingAdvice(IllegalArgumentException ex){
System.out.println("There has been an exception: " + ex.toString());
}
}
以下是Student.java文件的內容:
package com.yiibai;
public class Student {
private Integer age;
private String name;
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
System.out.println("Age : " + age );
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
System.out.println("Name : " + name );
return name;
}
public void printThrowException(){
System.out.println("Exception raised");
throw new IllegalArgumentException();
}
}
以下是MainApp.java文件的內容:
package com.yiibai;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
Student student = (Student) context.getBean("student");
student.getName();
student.getAge();
student.printThrowException();
}
}
以下是設置裝備擺設文件beans.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/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:config>
<aop:aspect id="log" ref="logging">
<aop:pointcut id="selectAll"
expression="execution(* com.yiibai.*.*(..))"/>
<aop:before pointcut-ref="selectAll" method="beforeAdvice"/>
<aop:after pointcut-ref="selectAll" method="afterAdvice"/>
<aop:after-returning pointcut-ref="selectAll"
returning="retVal"
method="afterReturningAdvice"/>
<aop:after-throwing pointcut-ref="selectAll"
throwing="ex"
method="AfterThrowingAdvice"/>
</aop:aspect>
</aop:config>
<!-- Definition for student bean -->
<bean id="student" class="com.yiibai.Student">
<property name="name" value="Zara" />
<property name="age" value="11"/>
</bean>
<!-- Definition for logging aspect -->
<bean id="logging" class="com.yiibai.Logging"/>
</beans>
創立源代碼和bean設置裝備擺設文件完成後,讓我們運轉運用法式。假如一切順遂,這將打印以下信息:
Going to setup student profile. Name : Zara Student profile has been setup. Returning:Zara Going to setup student profile. Age : 11 Student profile has been setup. Returning:11 Going to setup student profile. Exception raised Student profile has been setup. There has been an exception: java.lang.IllegalArgumentException ..... other exception content
說明一下,下面界說<aop:pointcut>選擇一切的包com.yiibai下界說的辦法。讓我們假定,想有一個特定的辦法之前或以後履行看法,可以界說切入點與現實的類和辦法的稱號代替星號(*)的切入點界說來減少履行。上面是修正後的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/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <aop:config> <aop:aspect id="log" ref="logging"> <aop:pointcut id="selectAll" expression="execution(* com.yiibai.Student.getName(..))"/> <aop:before pointcut-ref="selectAll" method="beforeAdvice"/> <aop:after pointcut-ref="selectAll" method="afterAdvice"/> </aop:aspect> </aop:config> <!-- Definition for student bean --> <bean id="student" class="com.yiibai.Student"> <property name="name" value="Zara" /> <property name="age" value="11"/> </bean> <!-- Definition for logging aspect --> <bean id="logging" class="com.yiibai.Logging"/> </beans>
假如履行這些設置裝備擺設更改的示例運用法式,這將打印以下信息:
Going to setup student profile. Name : Zara Student profile has been setup. Age : 11 Exception raised ..... other exception content
基於@AspectJ的AOP
@ AspectJ是指聲明方面的作風正文的應用Java 5正文通俗的Java類。對@ AspectJ支撐由包含您基於XML Schema的設置裝備擺設文件外面的以下元素啟用。
<aop:aspectj-autoproxy/>
您還須要在以下運用法式的類途徑中的AspectJ庫。這些庫可以在AspectJ的裝置的'lib'目次,可以從網高低載他們.
聲明一個切面
方面類是像任何其他通俗的bean,並能夠無方法和字段,就像任何其他類,但他們將被標注了@Aspect 以下:
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AspectModule {
}
他們將在XML中停止設置裝備擺設像任何其他的bean,以下所示:
<bean id="myAspect" class="org.xyz.AspectModule"> <!-- configure properties of aspect here as normal --> </bean>
聲明一個切入點
一個切入點有助於肯定與分歧看法要履行的銜接點的權益(即辦法)。同時用@AspectJ的基本設置裝備擺設任務,切入點聲明有兩個部門:
切入點表達式,決議哪些辦法履行我們感興致
一個切入點簽名的包括名字和隨意率性數目的參數。該辦法的現實主體是不相干的,現實上應為空。
上面的示例界說一個名為'businessService“切入點將婚配每一個辦法的可用包com.xyz.myapp.service下履行中的類:
import org.aspectj.lang.annotation.Pointcut;
@Pointcut("execution(* com.xyz.myapp.service.*.*(..))") // expression
private void businessService() {} // signature
上面的示例界說一個名為'getName'切入點將婚配可用的軟件包com.yiibai下履行getName()辦法在Student類:
import org.aspectj.lang.annotation.Pointcut;
@Pointcut("execution(* com.yiibai.Student.getName(..))")
private void getname() {}
聲明建議
可以聲明任何應用 @{ADVICE-NAME} 正文上面給出的五個建議。這假定曾經界說了一個切入點簽名的辦法的businessService():
@Before("businessService()")
public void doBeforeTask(){
...
}
@After("businessService()")
public void doAfterTask(){
...
}
@AfterReturning(pointcut = "businessService()", returning="retVal")
public void doAfterReturnningTask(Object retVal){
// you can intercept retVal here.
...
}
@AfterThrowing(pointcut = "businessService()", throwing="ex")
public void doAfterThrowingTask(Exception ex){
// you can intercept thrown exception here.
...
}
@Around("businessService()")
public void doAroundTask(){
...
}
可以界說內置切入點的任何看法的。上面是一個例子界說內聯的切入點之前的建議:
@Before("execution(* com.xyz.myapp.service.*.*(..))")
public doBeforeTask(){
...
}
@AspectJ 基於AOP例子
要懂得上述關系到@AspectJ的AOP的基本概念提到,讓我們寫這將完成幾個建議的一個例子。
這裡是Logging.java文件的內容。這現實上是方面模塊的一個示例,它界說的辦法被挪用的各個點。
package com.yiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
@Aspect
public class Logging {
/** Following is the definition for a pointcut to select
* all the methods available. So advice will be called
* for all the methods.
*/
@Pointcut("execution(* com.yiibai.*.*(..))")
private void selectAll(){}
/**
* This is the method which I would like to execute
* before a selected method execution.
*/
@Before("selectAll()")
public void beforeAdvice(){
System.out.println("Going to setup student profile.");
}
/**
* This is the method which I would like to execute
* after a selected method execution.
*/
@After("selectAll()")
public void afterAdvice(){
System.out.println("Student profile has been setup.");
}
/**
* This is the method which I would like to execute
* when any method returns.
*/
@AfterReturning(pointcut = "selectAll()", returning="retVal")
public void afterReturningAdvice(Object retVal){
System.out.println("Returning:" + retVal.toString() );
}
/**
* This is the method which I would like to execute
* if there is an exception raised by any method.
*/
@AfterThrowing(pointcut = "selectAll()", throwing = "ex")
public void AfterThrowingAdvice(IllegalArgumentException ex){
System.out.println("There has been an exception: " + ex.toString());
}
}
以下是Student.java文件的內容:
package com.yiibai;
public class Student {
private Integer age;
private String name;
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
System.out.println("Age : " + age );
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
System.out.println("Name : " + name );
return name;
}
public void printThrowException(){
System.out.println("Exception raised");
throw new IllegalArgumentException();
}
}
以下是MainApp.java文件的內容:
package com.yiibai;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
Student student = (Student) context.getBean("student");
student.getName();
student.getAge();
student.printThrowException();
}
}
以下是設置裝備擺設文件beans.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/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <aop:aspectj-autoproxy/> <!-- Definition for student bean --> <bean id="student" class="com.yiibai.Student"> <property name="name" value="Zara" /> <property name="age" value="11"/> </bean> <!-- Definition for logging aspect --> <bean id="logging" class="com.yiibai.Logging"/> </beans>
創立源法式和bean設置裝備擺設文件完成後,讓我們運轉運用法式。假如一切順遂,這將打印以下信息:
Going to setup student profile. Name : Zara Student profile has been setup. Returning:Zara Going to setup student profile. Age : 11 Student profile has been setup. Returning:11 Going to setup student profile. Exception raised Student profile has been setup. There has been an exception: java.lang.IllegalArgumentException ..... other exception content