Spring AOP的注解方式在官网的doc文档里也有详细的说明:http://docs.spring.io/spring/docs/2.0.8/reference/aop.html
还是上篇日志的示例工程,现在换成Annotation注解的方式来配置AOP,工程结构一样的:
AllLogAdvice类代码变成了如下:
package com.aop; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class AllLogAdvice { private Logger logger = Logger.getLogger(AllLogAdvice.class); // @Pointcut("execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))") // @Pointcut("within(com.test.spring.aop.pointcutexp..*)") // @Pointcut("this(com.test.spring.aop.pointcutexp.Intf)") // @Pointcut("target(com.test.spring.aop.pointcutexp.Intf)") // @Pointcut("@within(org.springframework.transaction.annotation.Transactional)") // @Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)") // @Pointcut("args(String)") @Pointcut("execution(* com.service.UserService.add*(..)) || execution(* com.service.UserService.delete*(..))") public void pointcut1() { // 定义一个pointcut,下面用Annotation标注的通知方法可以公用这个pointcut } // 前置通知 // 拦截参数为一个String类型的方法 @Before("pointcut1() && args(temp)") public void myBeforeAdvice(String temp) {// 如果需要知道拦截的方法的信息,也可以需添加JoinPoint参数 String logInfoText = "这是前置通知" + temp; // 将日志信息写入配置的文件中 logger.info(logInfoText); } // 后置通知 // 拦截 返回类型为String 的方法 @AfterReturning(pointcut = "pointcut1()", returning = "result") public void myAfterReturnAdvice(String result) { logger.info("这是后置通知 " + " result: " + result); } // 最终置通知 @After("execution(* com.service.UserService.add*(..))") public void doAfter() { logger.info("这是最终通知"); } // 异常通知 @AfterThrowing(pointcut = "pointcut1()", throwing = "e") 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); } // 环绕通知 // @Around(value="pointcut1()") @Around("pointcut1()") public Object myAroundAdvice(ProceedingJoinPoint jionpoint) throws Throwable { // 获取被调用的方法名 String targetMethodName = jionpoint.getSignature().getName(); Object o = jionpoint.proceed(); String logInfoText = "这是环绕通知:" + targetMethodName; logger.info(logInfoText); //Object o = jionpoint.proceed();//注意写到这儿的话,环绕通知和其它通知的顺序 return o; } }
代码里加了很多注释说明,注意这儿多了一个最终通知。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> <bean id="allLogAdvice" class="com.aop.AllLogAdvice"></bean> <aop:aspectj-autoproxy /> <!-- 如果不声明AllLogAdvice的bean,可以在com.aop下的类加上@Component <context:component-scan base-package="com.aop"/> --> </beans>
注意这里添加了<aop:aspectj-autoproxy />,而且声明了com.aop.AllLogAdvice的bean,如果不声明这个bean的话,在这个类的头上添加@Component,然后通过component-scan扫描也可以。
这儿我把UserService类稍微改了一下:
package com.service; public class UserService implements IUserService { public int addUser(String name, int age) { //省略诸如操作数据库等复杂的逻辑操作 System.out.println("add user "+ name +" successfully"); return 1; } public void deleteUser(String name) { //省略诸如操作数据库等复杂的逻辑操作 System.out.println("deleted one user named " + name); //throw new RuntimeException("这是特意抛出的异常信息!"); } }
addUser方法改成了int型的返回值,deleteUser方法依然是void。
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"); } }
好啦,看看执行结果:
add user ton successfully [INFO ] [14:48:43] com.aop.AllLogAdvice - 这是最终通知 [INFO ] [14:48:43] com.aop.AllLogAdvice - 这是环绕通知:addUser [INFO ] [14:48:43] com.aop.AllLogAdvice - 这是前置通知ton deleted one user named ton [INFO ] [14:48:43] com.aop.AllLogAdvice - 这是后置通知 result: null [INFO ] [14:48:43] com.aop.AllLogAdvice - 这是环绕通知:deleteUser
结果发现,后置通知本来是要拦截返回值是String的方法,addUser确实没有被拦截,但是deleteUser明明是void也被拦截了。
工程代码在附件中。。。
相关推荐
SpringAOP的注解配置完成切面的编程,完成execution,annotation两种表达式的实例Ddemo
两行为开启spring的注解配置 <aop:aspect id="aspect" ref="logIntercepter"> 引入具体的AOP操作类 <aop:pointcut expression="execution(* com.spring.service..*(..))" id="pointCut"/>声明一个切入点,注意...
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <!-- apache.dbcp连接池的配置 --> ...
-- 采用单数据源事务控制方式,通过注解来定义事务--> class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <bean id="viewResolver" class="org.springframework.web.servlet....
(一) Annotation注解方式配置事务管理 31 (二) Spring事务选项 35 (三) XML文件形式配置Spring事务管理 37 四、 HibernateTemplate 38 (一) HibernateTemplate 38 (二) HibernateDaoSupport 39 第十一课:Spring整合...
com-aop注释权限演示
Android AOP注解Annotation详解(一) Android AOP之注解处理解释器详解(二) Android AOP 注解详解及简单使用实例(三) 一、简介 在Android 里面 注解主要用来干这么几件事: 和编译器一起给你一些提示警告信息...
spring3.2+strut2+hibernate4 注解方式。 spring.xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=...
本篇文章主要介绍了详解Spring Aop实例之AspectJ注解配置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
注解配置 org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean 配置形式: org.springframework.orm.hibernate3.LocalSessionFactoryBean --> ...
注解配置 org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean 配置形式: org.springframework.orm.hibernate3.LocalSessionFactoryBean --> ...
(一) Annotation注解方式配置事务管理 31 (二) Spring事务选项 35 (三) XML文件形式配置Spring事务管理 37 四、 HibernateTemplate 38 (一) HibernateTemplate 38 (二) HibernateDaoSupport 39 第十一课:Spring整合...
弃用了struts,用spring mvc框架做了几个项目,感觉都不错,而且使用了注解方式,可以省掉一大堆配置文件。本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mvc和rest小例子没有介绍到数据层的内容,...
4.10.2 使用注解配置信息启动Spring容器 4.10.3 自动装配Bean 4.10.4 Bean作用范围及生命过程方法 4.11 基于Java类的配置 4.11.1 使用Java类提供Bean定义信息 4.11.2 使用基于Java类的配置信息启动Spring容器 4.12 ...
在上添加@Transactional注解并不会完成事务切面的织入,还需要在配置文件中加一行配置,通知spring容器对标了@Transactional的bean进行处理,织入事务。 在applicationContext-tx.xml文件上加上tx:annotation-driven...
2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.3.3. 对bean命名pointcut( bean name pointcut element)...
--通过添加了以下内容来使用注解方式配置权限.... <!-- Support Shiro Annotation 必须放在springMVC配置文件中 --> <!-- 异常处理,权限注解会抛出异常,根据异常返回相应页面 --> class="org.spring...
2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.3.3. 对bean命名pointcut( bean name pointcut ...