AOP 面向切面编程
为什么要用面向切面编程
第一天
===是这样的,在保存用户之前,想进行一下权限验证,例如只有管理员才能进行用户保存
===那这个类里面增加了一个checkPrivilege()方法把,save()中直接调用就可以啦,完美解决,下班
第二天
===嗯。。。,在增加商品的之前,我也想进行一下权限验证,和昨天一样
===嗯。。。和昨天一样啊,不同类之间用继承好啦,咚咚咚,BaseDaoImpl完成,再加上checkPrivilege()方法,来来来,大家都继承一下就可以啦,耶,下班
第三天
===哎。。。用继承是没错啦,但是思想上不对呀,User和Product怎么能继承一样的类呢,那还能怎么办呢,走走走,百度去!
===哇,面向切面编程,不明觉厉,赶紧一起学习一下吧
AOP相关术语
Aop两种代理方式( 以下代码理解即可,在spring中均已封装好,无需手写)
AOP实战(JDK动态代理)
结构:
public interface UserDao { void save(); void delete(); void update(); void find(); }
public class UserDaoImpl implements UserDao { @Override public void save() { System.out.println("保存用户。。。 "); } @Override public void delete() { System.out.println("删除用户。。。 "); } @Override public void update() { System.out.println("更新用户。。。 "); } @Override public void find() { System.out.println("查询用户。。。 "); } }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class MyJdkProxy implements InvocationHandler { private UserDao userDao; public MyJdkProxy(UserDao userDao) { this.userDao = userDao; } public Object createProxy(){ Object proxy = Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(),this); return proxy; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("save".equals(method.getName())){ System.out.println("权限校验。。。"); return method.invoke(userDao,args); }else{ return method.invoke(userDao,args); } } }
import org.junit.Test; public class UserTest { @Test public void test1(){ UserDao userDao = new UserDaoImpl(); UserDao proxy =(UserDao) new MyJdkProxy(userDao).createProxy(); proxy.delete(); proxy.find(); //在save之前做权限的校验 proxy.save(); proxy.update(); } }
AOP实战(CGLIB动态代理)
结构:
public class ProductDao { public void save() { System.out.println("保存用户。。。 "); } public void delete() { System.out.println("删除用户。。。 "); } public void update() { System.out.println("更新用户。。。 "); } public void find() { System.out.println("查询用户。。。 "); } }
import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class MyCglibProxy implements MethodInterceptor { private ProductDao productDao; public MyCglibProxy(ProductDao productDao) { this.productDao = productDao; } public Object createProxy(){ //1.创建核心类 Enhancer enhancer = new Enhancer(); //2.设置父类 enhancer.setSuperclass(productDao.getClass()); //3.设置回调 enhancer.setCallback(this); //生成代理 Object proxy = enhancer.create(); return proxy; } @Override public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { if("save".equals(method.getName())){ System.out.println("权限校验。。。"); } return methodProxy.invokeSuper(proxy,objects); } }
import org.junit.Test; public class ProductTest { @Test public void test1(){ ProductDao productDao = new ProductDao(); ProductDao proxy = (ProductDao)new MyCglibProxy(productDao).createProxy(); proxy.delete(); proxy.find(); //在save之前做权限的校验 proxy.save(); proxy.update(); } }