筆記之用……
首先有一個接口UserService
package com.spring.test;
import org.springframework.stereotype.Component;
@Component
public interface UserService {
public void createUser();
public void deleteUser();
public void updateUser(int id);
}
UserDao實現UserService
package com.spring.test;
import org.springframework.stereotype.Component;
@Component
public class UserDao implements UserService {
public void createUser() {
System.out.println("user saved...");
}
public void deleteUser(){
System.out.println("delete user...");
}
public void updateUser(int id){
System.out.println("update user...");
}
}
想要在這些方法執行的時候加一些業務邏輯,如公共日誌或者計算方法執行前後的時間等,將代碼以切面的形式切入到方法中,此時可以用動態代理來實現,
aop的動態代理底層是用jdk的動態代理實現的proxy和InvocationHandler,需實現 java.lang.reflect.InvocationHandler
首先定義一個LogInteceptor來實現InvocationHandler:
package com.spring.log;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;
/*****************
* 日誌類
*
* @author Administrator
*
*/
public class LogInteceptor implements InvocationHandler{
private Object target;//被代理的對象
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
beforeMethod(method);//在方法執行前所要執行的業務邏輯
long starttime=System.currentTimeMillis();
method.invoke(target, args);
long result=System.currentTimeMillis()-starttime;
System.out.println("執行時間爲:"+result+"毫秒");
afterMethod(method);//在方法執行後所要執行的業務邏輯
return null;
}
public void beforeMethod(Method m){
System.out.println(m.getName()+"執行before....");
}
public void afterMethod(Method m){
System.out.println(m.getName()+"執行after...");
}
}
然後用JUnit來進行測試
package com.junit.test;
import java.lang.reflect.Proxy;
import com.spring.log.LogInteceptor;
import com.spring.test.UserDao;
import com.spring.test.UserService;
public class Test {
@org.junit.Test
public void testProxy(){
UserDao userDao=new UserDao();//被代理的對象
LogInteceptor logInteceptor=new LogInteceptor();//獲取日誌的InvocationHandler
logInteceptor.setTarget(userDao);//把被代理的對象設爲userDao
//設置代理對象,參數1:被代理對象的classloader,參數2:被代理對象所實現的接口(該對象必須要實現接口,不然無法產生代理),參數3:指定處理的InvocationHandler
UserService userService=(UserService)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), new Class[]{UserService.class}, logInteceptor);
userService.createUser();//執行方法
userService.deleteUser();//執行方法
userService.updateUser(1001);//執行方法
}
}
createUser執行before....
user saved...
---執行時間爲:0毫秒
createUser執行after...
deleteUser執行before....
delete user...
---執行時間爲:0毫秒
deleteUser執行after...
updateUser執行before....
update user...
---執行時間爲:0毫秒
updateUser執行after...
接下來來點實際的..........................
定義一個LogInterceptor,讓dao裏的方法在執行的前後執行某些特定的方法
package com.spring.log;
public class LogInterceptor {
public void beforeMethod(){
System.out.println("方法執行前執行");
}
public void afterMethod(){
System.out.println("方法執行後執行");
}
}
定義的beforeMethod和afterMethod在applicationContext.xml裏用aop配置
<bean id="mylog" class="com.spring.log.LogInterceptor"></bean>
<aop:config>
<aop:aspect id="log" ref="mylog">
<aop:pointcut expression="execution (* com.spring.test.*.*(..))" id="point" /><!--切入點-->
<aop:before method="beforeMethod" pointcut-ref="point"/><!-- 定義方法before前執行自己定義的beforeMethod -->
<aop:after method="afterMethod" pointcut-ref="point"/><!-- 定義方法after後執行自己定義的afterMethod -->
</aop:aspect>
</aop:config>
當然還可以配置
<aop:around method=""/>
<aop:after-returning method=""/>
<aop:after-throwing method=""/>
最後用JUnit測試:
@org.junit.Test
public void Test(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service = (UserService) ctx.getBean("userDao");
service.createUser();
}
執行結果:
方法執行前執行
user saved...
方法執行後執行
如果要獲取執行的類和方法,可以接一個JoinPoint參數,用來獲取執行的方法名
package com.spring.log;
import org.aspectj.lang.JoinPoint;
public class LogInterceptor {
public void beforeMethod(JoinPoint point){
System.out.println("方法執行前執行");
//System.out.println(point.getTarget());//獲取類com.spring.test.UserDao@15e0873
//System.out.println(point.getSignature().getName());//獲取方法名
System.out.println(point.getTarget()+"類的"+point.getSignature().getName()+"方法執行!!!");
}
public void afterMethod(JoinPoint point){
System.out.println("方法執行後執行");
System.out.println(point.getTarget()+"類的"+point.getSignature().getName()+"方法執行完畢!!!");
}
}