http://blog.csdn.net/yaguanzhou2014/article/details/43063567?ref=myread
Spring——AOP模拟
AOP模拟实现
(1)AOP的含义:
a) 面向切面编程(Aspect Oriented Programming)
b) 是面向对象的思维方式的一个补充
(2)场景:
a) 现在需要在某些方法执行的时候,在其前后加一些日志
b) 例如:现在需要在UserDAO中的save()方法前后加上一些日志
c) 可选的方法如下:
i. 直接修改save()方法,在其前后增加一些所需要的代码
package com.zgy.impl;
import com.zgy.dao.UserDAO;
import com.zgy.model.User;
public class UserDAOImpl implements UserDAO{
@Override
public void save(User u) {
//直接修改方法
System.out.println("save start ...");
System.out.println("user saved");
}
}
ii. 继承接口的实现类:
1. 在com.zgy.impl包中在生成一个类UserDAOImpl2用于继承UserDAOImpl。在此类中新增所需要的方法,然后继承父类UserDAO中的save()方法,也可以实现功能。
package com.zgy.impl;
import com.zgy.model.User;
public class UserDAOImpl2 extends UserDAOImpl{
@Override
public void save(User u) {
//继承实现类
System.out.println("save start ...");
super.save(u);
}
}
iii. 组合:
1. 在在com.zgy.impl包中在生成一个UserDAOImpl3继承了UserDAO接口,在其中增加一个UserDAOImpl对象
package com.zgy.impl;
import com.zgy.dao.UserDAO;
import com.zgy.model.User;
public class UserDAOImpl3 implements UserDAO{
//组合
UserDAO userDAO = new UserDAOImpl();
public void save(User u) {
System.out.println("save start ...");
userDAO.save(u);
}
}
(3)当有多个bean都需要加入相同的方法的时候,可以将这个方法单独出来,在每个需要的bean中调用该方法即可
package com.zgy.aop;
public class LogInterceptor {
public void beforeMethod(){
System.out.println("save start ...");
}
}
(4)动态代理是AOP中重要的实现原理
a) 动态代理涉及的类:Proxy、InvocationHandler
b) 动态代理的实现:
i. 定义一个接口UserDAO,其中有两个方法:save()和delete()
package com.zgy.dao;
import com.zgy.model.User;
public interface UserDAO {
public void save(User u);
public void delete(User u);
}
ii. UserDAOImpl实现了UserDAO接口
package com.zgy.impl;
import com.zgy.dao.UserDAO;
import com.zgy.model.User;
public class UserDAOImpl implements UserDAO{
@Override
public void save(User u) {
//直接修改方法
//System.out.println("save start ...");
System.out.println("user saved");
}
@Override
public void delete(User u) {
System.out.println("User deleted");
}
}
iii. LogInterceptor实现了InvovationHandler接口
package com.zgy.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class LogInterceptor implements InvocationHandler {
private Object target;//被代理的对象
public void beforeMethod(Method m){
System.out.println(m.getName()+"start ...");
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
beforeMethod(method);
method.invoke(target, args);
return null;
}
}
iv. JUnit单元测试
package com.zgy.service;
import java.lang.reflect.Proxy;
import org.junit.Test;
import com.zgy.aop.LogInterceptor;
import com.zgy.dao.UserDAO;
import com.zgy.impl.UserDAOImpl;
import com.zgy.model.User;
public class UserServiceTest {
@Test
public void testProxy(){
UserDAO userDAO = new UserDAOImpl();
LogInterceptor interceptor = new LogInterceptor();
interceptor.setTarget(userDAO);
UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader()
, new Class[]{UserDAO.class}, interceptor);
userDAOProxy.delete(new User());
userDAOProxy.save(new User());
}
}
v. 运行结果:
deletestart ...
User deleted
savestart ...
user saved
vi. 作用:
当调用不同的方法时,会自动为在方法的前后加上save()、delete()方法,可以通过变化save()和delete()方法来实现不同的功能,如:记录日志、权限管理等等