笔记之用……
首先有一个接口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()+"方法执行完毕!!!");
}
}