作为这个介绍Spring框架中的面向方面编程(Aspect-Oriented Programming,AOP)的系列的第一部分,本文介绍了使您可以使用Spring中的面向方面特性进行快速开发的基础知识。使用跟踪和记录方面(面向方面领域的HelloWorld)作为例子,本文展示了如何使用Spring框架所独有的特性来声明切入点和通知以便应用方面。本系列的第二部分将更深入地介绍如何运用Spring中的所有通知类型和切入点来实现更实用的方面和面向方面设计模式。
本文的目的不是要介绍构成模块化J2EE系统——即Spring框架——的所有重要元素,我们将只把注意力放在Spring所提供的AOP功能上。由于Spring的模块化设计方法,我们可以只使用该框架的AOP元素,而无需对构成Spring框架的其他模块做太多考虑。
在AOP方面,Spring提供了什么? “它的目标不是提供最完善的AOP实现(虽然Spring AOP非常强大);而是要提供AOP实现与Spring IoC的紧密集成,以便帮助解决企业应用中的常见问题。”
Spring Framework参考文档
为了实现这个目标,Spring框架目前支持一组AOP概念,从切入点到通知。本文将展示如何使用Spring框架中所实现的如下AOP概念:
通知(Advice):如何将before通知、afterReturning通知和afterThrowing通知声明为bean。
切入点(Pointcut):如何声明静态切入点逻辑以将XML Spring Bean Configuration文件中的所有内容联系在一起。
Advisor:关联切入点定义与通知bean的方式。
设置场景:一个简单的例子应用程序 “一般而言,Spring并不是预描述的。虽然使用好的实践非常容易,但是它避免强制推行一种特定的方法。”
Spring Framework参考文档
要试用Spring框架的AOP功能,首先我们要创建一个简单的Java应用程序。IbusinessLogic接口和BusinessLogic类为Spring框架中的bean提供了简易构件块。虽然该接口对于我们的简单应用程序逻辑来说不是必需的,但是它是Spring框架所推荐的良好实践。
public interface IBusinessLogic { public void foo(); }
public class BusinessLogic implements IBusinessLogic { public void foo() { System.out.println("Inside BusinessLogic.foo()"); } } |
可以编写MainApplication类,借此练习BusinessLogic bean的公有方法。
import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext;
public class MainApplication { public static void main(String [] args) { // Read the configuration file ApplicationContext ctx = new FileSystemXmlApplicationContext("springconfig.xml");
//Instantiate an object IBusinessLogic testObject = (IBusinessLogic) ctx.getBean("businesslogicbean");
// Execute the public // method of the bean testObject.foo(); } } |
在BusinessLogic类及其关联接口中没有什么需要注意的。但是,MainApplication类初始化BusinessLogic对象的方式很有意思。通过使用ctx.getBean("businesslogicbean")调用,MainApplication将加载和管理BusinessLogic类的bean实例的任务转交给了Spring框架。
允许Spring控制BusinessLogic bean的初始化,这使得Spring运行时有机会在bean被返回给应用程序之前执行J2EE系统所需的所有与bean相关的管理任务。然后Spring运行时配置可以决定对bean应用哪些任务和模块。该配置信息由一个XML文件提供,类似于下面所示的:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- Bean configuration --> <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>IBusinessLogic</value> </property> <property name="target"> <ref local="beanTarget"/> </property> </bean> <!-- Bean Classes --> <bean id="beanTarget" class="BusinessLogic"/>
</beans> |
该配置文件,即springconfig.xml,指定要加载一个接口与IbusinessLogic相匹配的bean。该bean随后被关联到BusinessLogic实现类。看起来好像是费了很大力气只为了加载一个简单的bean并调用一个方法,但是您要知道,这个配置文件只是使Spring框架可以透明地对应用程序应用其组件的众多特性的一个体现。
图1显示了基本的顺序图:MainApplication原样执行,没有应用方面。
图1.没有对BusinessLogic bean应用方面时的顺序图 应用方法跟踪(Method Tracing)方面
可能最基本的方面就是方法跟踪方面了。这可能是您找得到的最简单的方面了,因此它是研究新的AOP实现的一个很好的起点。
方法跟踪方面在一个目标应用程序内捕获对所跟踪的方法的调用以及方法的返回值,并以某种方式显示这种信息。在AOP中,通知的before和after类型用于捕获这些类型的联结点,因为这两种通知可以在方法调用联结点之前或之后触发。使用Spring框架,方法跟踪方面的before通知是在TracingBeforeAdvice类中声明的。
import java.lang.reflect.Method; import org.springframework.aop. MethodBeforeAdvice;
public class TracingBeforeAdvice implements MethodBeforeAdvice { public void before(Method m, Object[] args, Object target) throws Throwable { System.out.println("Hello world! (by " + this.getClass().getName() + ")"); } } | 类似地,after通知可以在TracingAfterAdvice类中声明。
import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice;
public class TracingAfterAdvice implements AfterReturningAdvice { public void afterReturning(Object object, Method m, Object[] args, Object target) throws Throwable { System.out.println("Hello world! (by " + this.getClass().getName() + ")"); } } | 这两个类都通过实现Spring框架的适当通知接口而表示了特定的通知。每种类型的通知都指定实现before(..)或afterReturning(..)方法,以便使Spring运行时可以告诉通知适当的联结点会在何时出现。值得注意的是,TracingAfterAdvice实际上是从AfterReturningAdvice扩展而来的,表示只有在联结点在无异常的情况下获得返回值时才运行通知。
为了将通知与应用程序中的适当联结点关联起来,必须对springconfig.xml进行一些修改。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- Bean configuration --> <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>IBusinessLogic</value> </property> <property name="target"> <ref local="beanTarget"/> </property> <property name="interceptorNames"> <list> <value>theTracingBeforeAdvisor</value> <value>theTracingAfterAdvisor</value> </list> </property> </bean> <!-- Bean Classes --> <bean id="beanTarget" class="BusinessLogic"/>
<!-- Advisor pointcut definition for before advice --> <bean id="theTracingBeforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="theTracingBeforeAdvice"/> </property> <property name="pattern"> <value>.*</value> </property> </bean>
<!-- Advisor pointcut definition for after advice --> <bean id="theTracingAfterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="theTracingAfterAdvice"/> </property> <property name="pattern"> <value>.*</value> </property> </bean<
<!-- Advice classes --> <bean id="theTracingBeforeAdvice" class="TracingBeforeAdvice"/> <bean id="theTracingAfterAdvice" class="TracingAfterAdvice"/>
</beans> | theTracingBeforeAdvisor和theTracingAfterAdvisor advisor被添加到前面所声明的businesslogicbean。每个advisor都可能截获所有bean所关联到的联结点。Advisor本身就是bean,而它唯一的作用就是将切入点定义与通知bean关联起来。本例中的切入点定义是在静态对象层次结构中指定相关联结点的正则表达式。
因为本例中使用了org.springframework.aop.support.RegexpMethodPointcutAdvisor切入点advisor,切入点逻辑是使用正则表达式指定的。正则表达式用于识别公有接口对IbusinessLogici接口的联结点。下面是一些可以用来指定IBusinessLogic接口上的不同联结点集合的正则表达式例子:
<value>.*</value>:该表达式选择advisor所关联到的一个或多个bean上的所有联结点。 <value>./IBusinessLogic/.foo</value>:该表达式只选择IbusinessLogic接口上的foo()方法的联结点。如果是advisor所关联到的bean,则该表达式只选择IBusinessLogic接口上的联结点。 | springconfig.xml文件中最后的bean声明指定实现通知bean的类。
既然已经指定了跟踪方面的正确配置,那么下一次执行MainApplication时,这些方面就会在初始化过程中被编织进去,而BusinessLogic bean中的所有方法都将被跟踪,如图2所示。
图2. 方法跟踪方面应用到BusinessLogic bean之后的顺序图(单击图像查看大图) | 方法跟踪方面和例子应用程序的源代码可在本文末尾的参考资料小节进行下载。 方面的重用
可以对方法跟踪方面进行扩展,提供一个稍微复杂的记录(Logging)方面。记录方面提供了一个很不错的重用例子,因为记录方面所需的许多特性都已经包含在方法跟踪方面中了。 在本例中,记录方面扩展了方法跟踪方面,以便显示附加的与(在应用程序的执行过程中)所引发的异常有关的信息。 要完全使用记录方面,需要对应用程序做一些更改。BusinessLogicException异常类提供了一个可以由IBusinessLogicInterface接口和BusinessLogic实现类新增的void bar()方法引发的异常。 public class BusinessLogicException extends Exception {}
public interface IBusinessLogic { public void foo();
public void bar() throws BusinessLogicException; }
public class BusinessLogic implements IBusinessLogic { public void foo() { System.out.println("Inside BusinessLogic.foo()"); }
public void bar() throws BusinessLogicException { System.out.println("Inside BusinessLogic.bar()"); throw new BusinessLogicException(); } } | MainApplication类现在将对void bar()方法进行一次额外的调用,并处理选中的、可能由该方法引发的异常。 import org.springframeworkcontext.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext;
public class MainApplication { public static void main(String [] args) { // Read the configuration file ApplicationContext ctx = new FileSystemXmlApplicationContext( "springconfig.xml");
//Instantiate an object IBusinessLogic testObject = (IBusinessLogic) ctx.getBean("businesslogicbean");
//Execute the public methods of the bean testObject.foo();
try { testObject.bar(); } catch(BusinessLogicException ble) { System.out.println("Caught BusinessLogicException"); } } } | 来自方法跟踪方面的TracingBeforeAdvice和TracingAfterAdvice通知可以整体重用。LoggingThrowsAdvice类为新的异常记录提供了通知。 import org.springframework.aop.ThrowsAdvice; import java.lang.reflect.Method;
public class LoggingThrowsAdvice implements ThrowsAdvice { public void afterThrowing(Method method, Object[] args, Object target, Throwable subclass) { System.out.println("Logging that a " + subclass + "Exception was thrown."); } } | 应用记录方面的最后一步是修改springconfig.xml配置文件,使其包含新添加的LoggingThrowsAdvice通知。 图3显示了运行MainApplication并使用Spring框架应用了记录方面的UML顺序图。 | 图3. 记录方面应用到BusinessLogic bean之后的顺序图(单击图像查看大图) 此处的记录方面清楚地说明了如何重用现有方面以及如何在Spring框架中使用通知的throws形式。通过为before和after通知声明新的通知来重写现有的方法跟踪方面实现,可以实现更复杂的记录方面,记录到更复杂的记录框架,比如LOG4J。关于记录方面和例子应用程序的源代码,请参见本文末尾的参考资料小节。 结束语 本文展示了使用Spring框架中的基本AOP结构所应用的一些简单方面。在本系列的下一篇文章中,我们将介绍一些更实用的方面,探讨方面的生命周期,使用Spring框架的around通知,并使用Spring来应用AOP模式。 |
分享到:
相关推荐
作为这个介绍Spring框架中的面向方面编程(Aspect-OrientedProgramming,AOP)的系列的第一部分,本文介绍了使您可以使用Spring中的面向方面特性进行快速开发的基础知识。使用跟踪和记录方面(面向方面领域的Hello...
Spring Framework作为Java开发中的核心框架,以其强大的功能和灵活的设计理念,深受广大开发者喜爱。本篇文章将聚焦于Spring Framework 4.3.5.RELEASE版本,详细解析其特性、核心组件以及如何利用官方文档进行学习和...
Spring框架是Java开发中的核心组件,它以依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented Programming, AOP)为核心,极大地简化了企业级应用的开发过程。这份“Spring基础学习资料”涵盖了...
本篇文章将聚焦于Spring Framework 4.2.1.RELEASE版本,详细解析其特性、核心组件以及官方文档的内容。 首先,Spring Framework 4.2.1.RELEASE是该框架的一个稳定版本,它在4.x系列中引入了许多改进和新特性,旨在...
"Introducing the Spring Framework" 是一篇关于Spring框架的入门文章,对于初学者来说,它提供了一个了解Spring基本概念和核心功能的良好起点。配合翻译,读者可以更深入地理解Spring框架的工作原理和如何在实际...
《实战C#.NET编程.Spring.NET.NHibernate从入门到精通》这本书是针对想要深入理解C#.NET平台,并希望结合Spring.NET和NHibernate框架进行高效开发的程序员所编写的。本篇文章将详细阐述这些关键知识点,帮助你从零...
Spring框架是Java开发中不可或缺的一部分,它以其强大的依赖注入(DI)和面向切面编程(AOP)功能,以及丰富的生态系统,成为了企业级应用开发的标准选择。本篇将详细介绍Spring框架的下载、安装以及基本配置过程。 ...
- **AOP(面向切面编程)**:可以用来实现事务管理、日志记录等功能,通过定义切面和通知,将这些通用逻辑与业务代码解耦。 - **Spring Data JPA**:简化了数据库操作,通过Repository接口即可完成CRUD操作,支持...
在Spring Boot中,AOP(面向切面编程)是一个强大的工具,用于实现代码的模块化,特别是关注点的分离。AOP允许我们定义横切关注点,如日志、事务管理或安全检查,并将这些关注点与核心业务逻辑解耦。在本篇文章中,...
在本篇 Spring 学习笔记中,我们将探讨 Spring 的入门、优点、组成以及重要的IOC理论。 1. **Spring 简介** Spring 是一个开源的、免费的 Java 框架,它的目标是减少企业级开发的复杂性。它集成了许多现有的技术,...
Spring的核心优势在于其对依赖注入(DI)的支持以及面向切面编程(AOP)的能力,这使得开发者可以更加关注业务逻辑而不是框架本身。 **Spring** 提供了一个“一站式”解决方案,旨在帮助开发者构建易于维护和扩展的...
"spring2.0-reference_final_zh_cn.pdf"是Spring 2.0中文参考手册,它详细阐述了Spring 2.0版本的功能和API,包括依赖注入、AOP(面向切面编程)、数据访问、事务管理等核心特性。尽管Spring已经发展到了更高的版本...
- **Spring AOP**:使用面向切面编程实现事务管理、日志记录等功能。 - **Spring Data JPA**:集成数据库操作,简化 CRUD 操作。 - **Spring Security**:提供安全控制,如认证、授权等。 - **Spring Boot**:快速...
本篇中文文档将详细介绍Spring和Hibernate的中文文档,包括Spring Framework的概述、Spring 3的新特性、核心技术以及Hibernate的入门、架构、配置等方面的知识。 Spring Framework是Java平台上的一个开源应用框架,...
在Struts-config.xml中,我们可以定义一个或多个`action`,并通过`className`属性指定`org.springframework.web.struts.DelegatingActionProxy`作为处理者。这样,Struts就可以调用Spring管理的bean来进行业务逻辑...
2. **Spring框架:** Spring是一个广泛使用的Java应用框架,提供依赖注入(DI)和面向切面编程(AOP),并支持多种Web应用开发,包括RESTful服务。 3. **Spring与Jersey集成:** 将Jersey集成到Spring环境中,可以...
拦截器是AOP(面向切面编程)的一种表现形式,它可以在方法调用前后执行特定的操作,如日志记录、权限检查、性能统计等。在Spring MVC中,拦截器可以拦截HTTP请求,进一步增强我们的应用程序功能。 要创建一个...