您的位置:首页 > 编程语言 > Java开发

Spring(三)AOP面向切面编程

2016-04-03 21:44 423 查看
原文链接:http://www.orlion.ga/205/

一、AOP简介

1、AOP概念

参考文章:http://www.orlion.ml/57

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());
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: