原文链接:http://www.orlion.ga/205/
一、AOP简介
1、AOP概念
2、AOP的产生
对于如下方法:
public class UserDAOImpl implements UserDAO{
public void saveUser(User user){
doSaveUser();
}
}
想在saveUser方法中执行保存用户之前和之后记录当前时间以求出saveUser花费了多少时间,方法有很多种,最直观的写法就是在doSaveUser()前后加代码取出当前时间:
public class UserDAOImpl implements UserDAO{
public void saveUser(User user){
int beginTime = getCurrentTime();
doSaveUser();
int endTime = getCurrentTime();
}
}
还有一种方法就是重新写一个类继承自UserDAOImpl然后重写saveUser方法,如下:
public class UserDAOImpl2 extends UserDAOImpl{
@Override
public void saveUser(User user){
int beginTime = getCurrentTime(); super.saveUser(); int endTime = getCurrentTime();
}
}
这种方法耦合性太强,一旦父类改变了子类也会改变,慎用继承
再有一种方法就是在调用saveUser()方法时加代码:
public class UserService{
public void saveUser(User user){
UserDAOImpl userDao = new UserDAOImpl();
int beginTime = getCurrentTime(); userDao.saveUser(); int endTime = getCurrentTime();
}
}
现在如果让我们将项目中所有的对数据库进行CRUD操作的方法都加上获取时间的代码,显然工作量太大,这时候就用动态代理: (可参考http://www.orlion.ml/207/)
UserDAOImpl.java
package ml.orlion.dao.impl;
import ml.orlion.dao.UserDAO;
import ml.orlion.model.User;
public class UserDAOImpl implements UserDAO{
public void saveUser(User user){
System.out.println("save usering");
}
}
TimeInterceptor.java
package ml.orlion.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TimeInterceptor implements InvocationHandler{
private Object target;// 被代理的对象
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public void beforeMethod(Method m){
System.out.println(m.getName() + "begin start");
}
@Override
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
this.beforeMethod(m);// 插入方法
m.invoke(target, args);
return null;
}
}
测试
public static void testProxy(){
// 首先产生一个被代理对象
UserDAO userDao = new UserDAOImpl();
// 下一步将被代理对象交给InvocationHandler即TimeInterceptor
TimeInterceptor ti = new TimeInterceptor();
// 设置被代理对象
ti.setTarget(userDao);
// 根据被代理对象产生一个代理
UserDAO userProxy = (UserDAO)Proxy.newProxyInstance(UserDAO.class.getClassLoader(), new Class[]{UserDAO.class}, ti);
userProxy.saveUser(new User());
}
运行可以看到控制台打印:saveUserbegin start save usering
二、使用Spring AOP
UserDAO.java:
package ml.orlion.dao; import ml.orlion.model.User; public interface UserDAO {
public void saveUser(User user);
}
UserDAOImpl.java:
package ml.orlion.dao.impl; import ml.orlion.dao.UserDAO;
import ml.orlion.model.User; public class UserDAOImpl implements UserDAO{ public void saveUser(User user){
System.out.println("save usering");
}
}
UserService.java
package ml.orlion.service; import ml.orlion.dao.UserDAO;
import ml.orlion.dao.impl.UserDAOImpl;
import ml.orlion.model.User; public class UserService { private UserDAO userDAO = new UserDAOImpl(); public UserDAO getUserDao() { return userDAO;
} public void setUserDao(UserDAO userDAO) {
this.userDAO = userDAO;
} public void saveUser(User user){
this.userDAO.saveUser(user);
}
}
LogInterceptor.java
package ml.orlion.aop; public class LogInterceptor { public void before(){
System.out.println("before");
}
}
beans.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"
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.xsd"> <bean id="logInterceptor" class="ml.orlion.aop.LogInterceptor">
</bean>
<bean id="userDao" class="ml.orlion.dao.impl.UserDAOImpl">
</bean>
<bean id="userService" class="ml.orlion.service.UserService">
<property name="userDao" ref="userDao"/>
</bean>
<aop:config>
<aop:pointcut expression="execution(public * ml.orlion.service..*.add(..))"
id="servicePointcut" />
<aop:aspect id="logAspect" ref="logInterceptor">
<aop:before method="before" pointcut-ref="servicePointcut"/>
</aop:aspect>
</aop:config>
</beans>
测试:
BeanFactory appContext = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) appContext.getBean("userService");
userService.saveUser(new User());