/**
* 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>