/**
* Spring AOP 使用方法
* 1、spring的xml文件中引入 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
* 2、使用AspectJ
* 2.1由于sping3.0之后不集成aspjectj的包了,所以需要另外下载aspjectj的包
* 地址:http://www.eclipse.org/aspectj/(其实就是eclipse个网 -_-||| )
* 3、在需要aop通知的类中加入@Aspect注解(扩展:如果有多个通知可以用@Order来指定顺序)
* 3.1通知一共有5种
* 前置通知:@before
* 后置通知:@After 后置通知 (即使有无异常都回执行,大致上等于java里的finally块)
* 返回通知:@AfterReturning 相当于调用方法成功获取到返回值
* 异常通知:@AfterThrowing 运行异常触发一下事件,大致相当于catch块
* 环绕通知:@Around 是上面4种通知的完整版本,能够实现上面所有通知功能,参数使用proceedingJoinPoint
* 3.2注解中用 (value="execution(返回类型 包名.类名.方法名(参数类型))")
* 例如:@After(value="execution(* com.text.UserCtrl(..))")
* 其中afterreturning需要指定returning(可以填写参数中的参数名)
* afterthrowing需要指定throwing
* 3.3前四个通知可以用Joinpoint 获取调用方法的相关参数
* 而Around则可以使用ProceedingJoinPoint
*
* 4、扩展(切点概念)参考JoinPointTest
* 指定切点 @Pointcut(value = "execution(* com.spring.contoller.UserController.*(..))") public void customerJoinPoint() { }
* 重用切点 @Before(value="customerJoinPoint()")
* @param args
*/
测试类:
package com.spring.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.contoller.UserController;
import com.spring.vo.User;
public class Test {
/**
* Spring AOP 使用方法
* 1、spring的xml文件中引入 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
* 2、使用AspectJ
* 2.1由于sping3.0之后不集成aspjectj的包了,所以需要另外下载aspjectj的包
* 地址:http://www.eclipse.org/aspectj/(其实就是eclipse个网 -_-||| )
* 3、在需要aop通知的类中加入@Aspect注解(扩展:如果有多个通知可以用@Order来指定顺序)
* 3.1通知一共有5种
* 前置通知:@before
* 后置通知:@After 后置通知 (即使有无异常都回执行,大致上等于java里的finally块)
* 返回通知:@AfterReturning 相当于调用方法成功获取到返回值
* 异常通知:@AfterThrowing 运行异常触发一下事件,大致相当于catch块
* 环绕通知:@Around 是上面4种通知的完整版本,能够实现上面所有通知功能,参数使用proceedingJoinPoint
* 3.2注解中用 (value="execution(返回类型 包名.类名.方法名(参数类型))")
* 例如:@After(value="execution(* com.text.UserCtrl(..))")
* 其中afterreturning需要指定returning(可以填写参数中的参数名)
* afterthrowing需要指定throwing
* 3.3前四个通知可以用Joinpoint 获取调用方法的相关参数
* 而Around则可以使用ProceedingJoinPoint
*
* 4、扩展(切点概念)参考JoinPointTest
* 指定切点 @Pointcut(value = "execution(* com.spring.contoller.UserController.*(..))") public void customerJoinPoint() { }
* 重用切点 @Before(value="customerJoinPoint()")
* @param args
*/
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//通过springioc获取bean
UserController ctrl = (UserController) ctx.getBean("userController");
//调用bean方法
ctrl.saveUser(new User("Super Man", 20));
//测试异常通知:ctrl.saveUser(new User("Super Man", 20));
}
}
logging类(aop使用类):
package com.spring.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LoggingTools {
/**
* 前置通知
* @param joinpoint
*/
@Before("execution(* com.spring.contoller.UserController.*(..))")
public void beforeLog(JoinPoint joinpoint){
Signature sign = joinpoint.getSignature();
System.out.println(" 前置通知 beforeAdvice ... "+sign.getName()+" params ... "+joinpoint.getArgs());
}
/**
* 后置通知 (即使有无异常都回执行,大致上等于java里的finally块)
* @param jp
*/
@After("execution(* com.spring.contoller.UserController.*(..))")
public void afterLog(JoinPoint jp){
System.out.println(" 后置通知 afterAdvice ... "+jp.getSignature().getName());
}
/**
* 返回通知:相当于调用方法成功获取到返回值
* @param jp
* @param result
*/
@AfterReturning(value="execution(* com.spring.contoller.UserController.*(..))",returning="result")
public void afterReturningLog(JoinPoint jp,Object result){
System.out.println(" 返回通知 afterReturingAdvice ... "+jp.getSignature().getName()+" the result is "+result);
}
/**
* 异常通知:运行异常触发一下事件,大致相当于catch块
* @param jp
* @param e
*/
@AfterThrowing(value="execution(* com.spring.contoller.UserController.*(..))",throwing="e")
public void afterThrowingLog(JoinPoint jp,Exception e){
System.out.println(" 异常通知 afterThrowingAdvice ... "+jp.getSignature().getName()+" exception is ... "+e);
}
/**
* 环绕通知,是上面4种通知的完整版本
* 能够实现上面所有通知功能
* 参数使用proceedingJoinPoint
* @param pjd
* @return
*/
/*@Around(value="execution(* com.spring.contoller.UserController.*(..))")
public Object aroundLog(ProceedingJoinPoint pjd){
Signature sign = pjd.getSignature();
Object[] args = pjd.getArgs();
Object result = null;
try {
System.out.println(" 前置通知 beforeAdvice ... "+sign.getName());
//if(args[0] instanceof User){
//return 0;
//}
result = pjd.proceed();//调用方法。。。
System.out.println(" 返回通知 afterReturingAdvice ... "+sign.getName()+" the result is "+result);
} catch (Throwable e) {
// TODO: handle exception
System.out.println(" 异常通知 afterThrowingAdvice ... "+sign.getName()+" exception is ... "+e);
throw new RuntimeException(e);
} finally{
System.out.println(" 后置通知 afterAdvice ... "+sign.getName());
}
return result;
}*/
}
切点使用类:
package com.spring.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Order(2)
public class JoinPointTest {
@Pointcut(value = "execution(* com.spring.contoller.UserController.*(..))")
public void customerJoinPoint() {
}
@Before(value="customerJoinPoint()")
public void beforeJoinPoint(){
System.out.println("before joinpoint test ... ");
}
}
实体类:
package com.spring.contoller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.spring.dao.UserDao;
import com.spring.vo.User;
@Controller
public class UserController {
@Autowired
private UserDao userDao;
public int saveUser(User user) {
// TODO Auto-generated method stub
return userDao.save(user);
}
}
package com.spring.dao;
import org.springframework.stereotype.Repository;
import com.spring.vo.User;
@Repository
public class UserDao {
public int save(User user) {
// TODO Auto-generated method stub
int money = 1000/user.getAge();
System.out.println("save user ... "+user+" , he has "+(1000/user.getAge())+" dollars");
return money;
}
}
package com.spring.vo;
import org.springframework.stereotype.Component;
@Component
public class User {
private String name;
private int age;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
applicationcontext.xml
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- spring定义要扫描的包 -->
<context:component-scan base-package="com.spring"></context:component-scan>
<!-- 自动扫描aop包 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>