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();
    }
}