SSM学习笔记之Spring代理

一、AOP概述

       AOP(面向切面编程)采用了横向抽取(代理)机制,取代了传统纵向继承体系的重复性代码。

二、AOP术语

    1.Joinpoint(连接点):指可以被拦截到的点,在spring中通常指方法。

    2.pointcut:指被拦截的点。

    3.Advice:指拦截之后的动作。

    4.Target:被增强的对象。

    5.Weaving:指创建代理对象的过程。

    6.Aspect:pointcut和Advice的组合。

三、JDK动态代理

   1.创建测试接口和类。

      UserDao

public interface UserDao {
    public void save();
    public void update();
    public void delete();
    public void find();
}

     UserDaoImp

public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("保存用户。。。");
    }

    public void update() {
        System.out.println("更新用户。。。");
    }

    public void delete() {
        System.out.println("删除用户。。。");
    }

    public void find() {
        System.out.println("查找用户。。。");
    }
}

   自定义代理类MyJdkProxy

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);//被增强的类的接口的类加载器,接口的信息,InvocationHandler实例
        return proxy;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  //增强方法
        if ("save".equals(method.getName())){
            System.out.println("权限校验");
            return method.invoke(userDao,args);
        }
        return method.invoke(userDao,args);
    }
}

4.测试类:

@Test
public void demo1(){
    UserDao dao = new UserDaoImpl();
    UserDao proxy = (UserDao) new MyJdkProxy(dao).createProxy();
    proxy.save();
    proxy.delete();
    proxy.find();
    proxy.update();
}

四、Cglib实现代理

1、为什么要使用cglib?

      对于那些没有实现接口的业务类,无法使用jdk动态代理,可以使用cglib,他会为你的类创建一个子类。

2、创建Demo类ProductDao

public class ProductDao {
    public void update(){
        System.out.println("修改商品");
    }
    public void delete(){
        System.out.println("删除商品");
    }
    public void find(){
        System.out.println("查找商品");
    }
    public void add(){
        System.out.println("增加商品");
    }
}

3.代理类

public class MyCjlib implements MethodInterceptor{
    private ProductDao dao;
    public  MyCjlib(ProductDao dao){
        this.dao = dao;
    }
    public Object createProxy(){
        //创建核心对象
        Enhancer enhancer= new Enhancer();
        //设置父类
        enhancer.setSuperclass(dao.getClass());
        //设置回调
        enhancer.setCallback(this);
        //产生代理对象
        Object proxy = enhancer.create();
        return proxy;
    }

    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
      if ("add".equals(method.getName())){
          System.out.println("代理方法执行了.....");
          return methodProxy.invokeSuper(o,objects);
      }
        return methodProxy.invokeSuper(o,objects);
    }
}

4.测试

@Test
public  void demo1() {
        ProductDao dao = new ProductDao();
        ProductDao proxy = (ProductDao) new MyCjlib(dao).createProxy();
    proxy.add();
    proxy.find();
    proxy.delete();
    proxy.update();
    }
}

五、总结

1.spring在运行期间动态的生成动态代理对象,不需要特殊的编译器。

2.spring aop底层是通过jdk动态代理和cglib进行织入。

3.若目标对象实现了接口,spring会使用java.lang.reflect.Proxy类代理。

4.若目标对象没有实现接口,spring会使用cglib生成目标对象的子类。

5.程序应该优先为实现了接口的类创建代理,便于程序解耦维护。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值