spring-aop学习【基于注解】
我个人觉得,这个好像就是用在定制日志输出上,和log4j很像。 用途: 如果业务方法调用每一步都需要详细的日志,那就用这个吧 好处就是: 方便维护,只包含业务代码 下面开始说明: 所需要的jar包: com.springsource.net.sf.cglib-2.2.0.jar 直接上代码: 声明一个接口 package com.spring.bean.aop; import java.util.List; /** * * @author Administrator * */ public interface UserService { // 打招呼 void say(); 获取年龄 int getValue(List<Integer> array,int index); } 这是接口的实现类 org.springframework.beans.factory.annotation.Autowired; org.springframework.stereotype.Service; Administrator * 实现类 */ @Service("userService") class UserServiceImpl implements UserService { * 自动装配use对象 @Autowired private User user; @Override say() { TODO Auto-generated method stub System.out.println("我叫"+user.getName()+",今年"+user.getAge()+"岁,你好!!"); } @Override index) { TODO Auto-generated method stub return array.get(index); } } 用户对象信息 org.springframework.stereotype.Component; * Administrator * 用户信息 @Component class User { String name; age; public String getName() { name; } setName(String name) { this.name = getAge() { age; } void setAge( age) { this.age = age; } } 然后是两个切面代码 java.util.Arrays; org.aspectj.lang.JoinPoint; org.aspectj.lang.ProceedingJoinPoint; org.aspectj.lang.annotation.After; org.aspectj.lang.annotation.AfterReturning; org.aspectj.lang.annotation.AfterThrowing; org.aspectj.lang.annotation.Around; org.aspectj.lang.annotation.Aspect; org.aspectj.lang.annotation.Before; org.aspectj.lang.annotation.Pointcut; org.springframework.core.annotation.Order; * 声明一个切面 * */ @Order(2 LoggingAspectj { pointcut(){ } /* *//***//* @Before("pointcut())") public void beforeMethod(JoinPoint joinPoint){ // 获得调用的方法名 String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); System.out.println("the method "+methodName+"begins with "+Arrays.asList(args)); } * 后置通知 * 该方法执行在被调用方法之后,报错也依然执行 * @After("pointcut())") public void afterMethod(JoinPoint joinPoint){ // 获得调用的方法名 String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); System.out.println("the method "+methodName+"Ends with "+Arrays.asList(args)); } * 返回通知,在方法返回结果之后执行,异常无返回值 * @AfterReturning(value="pointcut())",returning="result") public void afterReturning(JoinPoint joinPoint,Object result){ // 获得调用的方法名 String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); System.out.println("the method "+methodName+"afterReturning with "+Arrays.asList(args)+" ["+result+"]"); } * 异常通知 * 在方法抛出异常之后 * @AfterThrowing(value="pointcut()",throwing="e") public void afterReturning(JoinPoint joinPoint,Exception e){ // 获得调用的方法名 String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); System.out.println("the method "+methodName+"afterThrowing with "+Arrays.asList(args)+e); }*/ * 环绕通知需要配合ProceedingJoinPoint使用,相当于动态代理 * pjp * @return @Around(value="pointcut()" Object aroundMethod(ProceedingJoinPoint pjp) { 获得调用的方法名 String methodName = pjp.getSignature().getName(); Object result = null; 调用目标方法 try { 前置通知 System.out.println("the method " + methodName + "Begins with " + Arrays.asList(pjp.getArgs())); result = pjp.proceed(); 后置通知 System.out.println("the method " + methodName + "Ends with " + Arrays.asList(pjp.getArgs())); 后置有返回值 System.out.println( "the method " + methodName + "Ends with " + Arrays.asList(pjp.getArgs()) + " [" + result + "]"); } catch (Throwable e) { TODO Auto-generated catch block 异常通知 System.out.println("the method " + methodName + "AfterThrowing with " + Arrays.asList(pjp.getArgs()) + e); e.printStackTrace(); 不加这句,会报错,因为result返回值为null throw new RuntimeException(e); } System.out.println("the method " + methodName + "LastEnds with " + Arrays.asList(pjp.getArgs())); result; } } 测试代码: java.util.ArrayList; org.springframework.context.ApplicationContext; org.springframework.context.support.ClassPathXmlApplicationContext; Main { static main(String[] args) { TODO Auto-generated method stub ApplicationContext ctx=new ClassPathXmlApplicationContext("bean-aop.xml"); UserService userServiceImpl=(UserService) ctx.getBean("userService"); User user=(User) ctx.getBean("user"); List<Integer> arrayList = new ArrayList<Integer>(); arrayList.add(1); arrayList.add(2); int age = userServiceImpl.getValue(arrayList,1); user.setName("xiaoqiang"); user.setAge(age); userServiceImpl.say(); } } bean文件 <?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:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 自动扫描的包 --> context:component-scan base-package="com.spring.bean.aop"></context:component-scan 使 AspectJ 的注解起作用 aop:aspectj-autoproxy> </beans> ? ?总结:
使用AspectJ方式注解需要相应的包--> dependency> groupId>org.aspectjartifactId>aspectjrtversion>${aspectj.version}> > --> >aspectjweaver> 2.为接口实现类添加注解@Component 3.编写一个切面类,配置切面 * 3.1 在配置文件中配置自动扫描的包: <context:component-scan base-package="com.spring.bean.aop"></context:component-scan> * 3.2 加入使 AspjectJ 注解起作用的配置: <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 4.编写前置通知方法,在方法上方添加注解 // 表达式注意格式: 修饰 +方法(有无返回)+包名+类名+方法名+参数
* @Before 表示在目标方法执行之前执行 @Before 标记的方法的方法体. 如关注详细参数,添加joinpoint对象,可以访问到方法的签名和参数 ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |