要使用本节所述的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'目录可用,可以从互联网上下载它们。
-
aspectjrt.jar
-
aspectjweaver.jar
-
aspectj.jar
声明一个切面
一个方面是使用<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提到的概念,让我们写这将实现几个建议的一个例子。写我们的例子中有一些建议,让我们使用Eclipse IDE,并按照下面的步骤来创建一个Spring应用程序:
步骤 | 描述 |
---|---|
1 | Create a project with a name SpringExample and create a package com.yiibai under the src folder in the created project. |
2 | Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter. |
3 | Add Spring AOP specific libraries aspectjrt.jar, aspectjweaver.jar and aspectj.jar in the project. |
4 | Create Java classes Logging, Student and MainApp under the com.yiibai package. |
5 | Create Beans configuration file Beans.xml under the src folder. |
6 | The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below. |
这里是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