Spring AOP提供了xml配置文件以及Annotation注解的方式更方便的进行AOP的配置。当然这两种方式的最大的好处是更好的降低了代码耦合性。
XML配置的示例工程代码:
和前面的工程相比,前置通知,后置通知那几个通知类没有了,所有的通知逻辑直接放到了AllLogAdvice类的方法里:
package com.aop;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class AllLogAdvice {
private Logger logger = Logger.getLogger(AllLogAdvice.class);
// 此方法将作为前置通知
public void myBeforeAdvice(JoinPoint jionpoint) {
// 获取被调用的类名
String targetClassName = jionpoint.getTarget().getClass().getName();
// 获取被调用的方法名
String targetMethodName = jionpoint.getSignature().getName();
// 日志格式字符串
String logInfoText = "前置通知:" + targetClassName + "类的"
+ targetMethodName + "方法开始执行";
// 将日志信息写入配置的文件中
logger.info(logInfoText);
}
// 此方法将作为后置通知
public void myAfterReturnAdvice(JoinPoint jionpoint) {
// 获取被调用的类名
String targetClassName = jionpoint.getTarget().getClass().getName();
// 获取被调用的方法名
String targetMethodName = jionpoint.getSignature().getName();
// 日志格式字符串
String logInfoText = "后置通知:" + targetClassName + "类的"
+ targetMethodName + "方法开始执行";
// 将日志信息写入配置的文件中
logger.info(logInfoText);
}
// 此方法将作为异常通知
public void myThrowingAdvice(JoinPoint jionpoint, Exception e) {
// 获取被调用的类名
String targetClassName = jionpoint.getTarget().getClass().getName();
// 获取被调用的方法名
String targetMethodName = jionpoint.getSignature().getName();
// 日志格式字符串
String logInfoText = "异常通知:执行" + targetClassName + "类的"
+ targetMethodName + "方法时发生异常";
// 将日志信息写入配置的文件中
logger.info(logInfoText);
}
// 此方法将作为环绕通知
public void myAroundAdvice(ProceedingJoinPoint jionpoint) throws Throwable {
long beginTime = System.currentTimeMillis();
jionpoint.proceed();
long endTime = System.currentTimeMillis();
// 获取被调用的方法名
String targetMethodName = jionpoint.getSignature().getName();
// 日志格式字符串
String logInfoText = "环绕通知:" + targetMethodName + "方法调用前时间" + beginTime
+ "毫秒," + "调用后时间" + endTime + "毫秒";
// 将日志信息写入配置的文件中
logger.info(logInfoText);
}
}
4种通知功能用4个方法来完成了。aop.xml配置文件内容:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <bean id="myUserService" class="com.service.UserService"></bean> <!-- 定义日志通知,将日志切面交给Spring容器管理 --> <bean id="allLogAdvice" class="com.aop.AllLogAdvice"></bean> <!-- 进行aop配置 --> <aop:config> <!-- 配置日志切面 --> <aop:aspect id="logaop" ref="allLogAdvice"> <aop:pointcut id="logpointcut" expression="execution(* com.service.UserService.*(..))" /> <!-- 将LogAdvice日志通知中的myBeforeAdvice方法指定为前置通知 --> <aop:before method="myBeforeAdvice" pointcut-ref="logpointcut"/> <!-- 将LogAdvice日志通知中的myAfterReturnAdvice方法指定为后置通知 --> <aop:after-returning method="myAfterReturnAdvice" pointcut-ref="logpointcut"/> <!-- 将LogAdvice日志通知中的方法指定为异常通知 --> <aop:after-throwing method="myThrowingAdvice" pointcut-ref="logpointcut" throwing="e" /> <!-- 将LogAdvice日志通知中的方法指定为环绕通知 --> <aop:around method="myAroundAdvice" pointcut-ref="logpointcut"/> </aop:aspect> </aop:config> </beans>
定义pointcut的这句:
<aop:pointcut id="logpointcut" expression="execution(* com.service.UserService.*(..))" />
expression里的写法参考官网解释的
6.2.3.4节:http://docs.spring.io/spring/docs/2.0.8/reference/aop.html
除了用execution外,还可以用within,this等。
这篇文章解释也不错:http://blog.csdn.net/kkdelta/article/details/7441829
这儿第一个*通配符代表所有的返回值,第二个*代表所有方法,(..)表示任意的参数类型。也就是说com.service.UserService类下面的所有任意返回值,任意参数类型的方法都会被拦截。
再看看主测试类MainTest:
package com.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.service.IUserService; public class MainTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "aop.xml"); IUserService userService = (IUserService) context .getBean("myUserService"); userService.addUser("ton", 56); userService.deleteUser("ton"); } }
这儿得到UserService的bean不再需要一个代理,而是直接用UserService定义的bean。这样的好处就是如果下次要删除通知里的逻辑,不再需要日志的功能了,我不再需要改java文件,直接在配置文件里的有关切面的配置段去掉就可以了,很好的做到了为代码解耦。
工程代码文件在附件中。。。。
相关推荐
演示了spring对aop的支持,包括注解方式、基于xml方式。
spring-aop-3.0.xsd 这个下载之后可以直接放在eclipese的xml的catalog中配置,已到达eclipse可以自动提示xml的功能
SpringAop xml方式配置通知
集成spring aop xml配置的必备文件,若想要application.xml中有aop节点提示,则必须添加spring-aop-3.0.xsd文件
在Spring1.2或之前的版本中,实现AOP的传统方式就是通过实现Spring的AOP API来定义Advice,并设置代理对象。Spring根据Adivce加入到业务流程的时机的不同,提供了四种不同的Advice:Before Advice、After Advice、...
spring-aop用xml方式完成的一个小实验
Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/aop] Offending resource: class path resource [beans.xml] at org....
基于xml代码的SpringAOP实例详解,适合初步学习springAOP的开发人员了解该功能的使用。
spring-framework-3.0.5.RELEASE-dependencies 好不容易找到了,赶紧分享一下 因为不能大于20M,共分了8个包,都是独立的,我列了目录,可以只下载需要的包,这是1号包: 1号包: edu.emory.mathcs.backport edu.oswego.cs....
用于编写spring的xml文件时的自动提示
java xml方式实现springaop编程,包含源码+jar包+解释
aop入门。
Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,AOP的原理就是java的动态代理机制
Spring AOP 的实现例子(基于XML配置实现); 具体介绍看这里:https://blog.csdn.net/qq_22078107/article/details/85865543
@Component("userService")等价于在spring配置文件中定义一个<bean id="userService"/> @Resource(name="userDAO")将userDA注入进来 写一个拦截器的类 package com.spring.aop; import org.springframework....
NULL 博文链接:https://panmingzhi0815.iteye.com/blog/1137678
XML配置SpringAOP共2页.pdf.zip
资料包含spring-iocdi-annotation-document,iocdi-annotation-mvc,iocdi-xml-extend,iocdi-annotation-extend proxy,jdkproxy-transaction,jdkproxy-salary,day02-itheima11-spring-08-cglibproxy,day02-itheima11-...