一间书店开始打折促销,规则是每一名顾客只能买一本书,而且已经脱销了,要求顾客进门,显示欢迎信息,当顾客买完书,显示欢送信息,没书时,请仓库赶快订货;使用基于XML的AspectJ完成
首先,我们需要定义一个切入点,来标识我们要拦截的方法,也就是顾客购买书的方法:
<aspectj:pointcut id="bookPurchase" expression="execution(* com.example.BookStore.purchaseBook(..))"/>
然后,我们需要定义一个切面,来实现我们的切面逻辑:
<aspectj:aspect id="discountAspect" ref="discountBean">
<aspectj:before pointcut-ref="bookPurchase" method="greetCustomer"/>
<aspectj:after-returning pointcut-ref="bookPurchase" method="thankCustomer"/>
<aspectj:after-throwing pointcut-ref="bookPurchase" throwing="ex" method="orderStock"/>
</aspectj:aspect>
这里定义了三个通知:
before通知,在执行切入点方法前执行,用于向顾客发送欢迎信息。
after-returning通知,在执行切入点方法后执行,用于向顾客发送欢送信息。
after-throwing通知,在切入点方法抛出异常时执行,用于向仓库发送订货信息。
在切面中,我们需要引用一个实现了具体逻辑的Bean,这里称为discountBean,并在aspect标签的ref属性中指定该Bean的ID。
下面是具体的实现代码:
public class Discount {
public void greetCustomer() {
System.out.println("Welcome to our book store!");
}
public void thankCustomer() {
System.out.println("Thank you for shopping with us!");
}
public void orderStock(Throwable ex) {
System.out.println("Sorry, the book is out of stock. Please order more.");
}
}
最后,我们需要在Spring配置文件中将切面和切入点关联起来:
<aop:config>
<aop:aspect id="discountAspect" ref="discountBean">
<aop:before pointcut-ref="bookPurchase" method="greetCustomer"/>
<aop:after-returning pointcut-ref="bookPurchase" method="thankCustomer"/>
<aop:after-throwing pointcut-ref="bookPurchase" throwing="ex" method="orderStock"/>
</aop:aspect>
</aop:config>
下面是一个基于XML的完整Spring配置文件示例,包含了定义Bean、依赖注入、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"
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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- 定义Bean -->
<bean id="bookDao" class="com.example.dao.BookDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="bookService" class="com.example.service.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</bean>
<!-- 依赖注入 -->
<bean id="bookController" class="com.example.controller.BookController">
<property name="bookService" ref="bookService"/>
</bean>
<!-- AOP配置 -->
<aop:aspectj-autoproxy/>
<bean id="myAspect" class="com.example.aspect.MyAspect"/>
<!-- 事务管理配置 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
其中,通过元素定义了三个Bean:bookDao、bookService和dataSource,并分别设置了它们的属性和依赖关系。通过元素实现依赖注入。在bookController中注入了bookService,从而实现了Controller和Service的解耦。通过aop:aspectj-autoproxy元素启用AspectJ切面自动代理功能,并通过元素定义切面类myAspect。通过tx:annotation-driven元素启用注解式事务管理。