Spring(三)AOP面向切面编程
原文链接: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());