Keep Thinking Keep Moving

Spring 标签

Cglib动态代理

在之前的文章中我们介绍了JDK动态代理的解析,今天我们来剖析一下Cglib的动态代理解析。

Cglib代理例子

按照惯例我们先用一个简单的例子来说明

HelloService被代理类:

public class HelloService {
    public void hello() {
        System.out.println("hello!");
    }
}

事务增强类MethodInterceptor:

public class TransactionIntercepter implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("开启事务!");
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("结束事务!");
        return object;
    }
    
}

2019-10-15 0 评论 75 浏览
阅读全文

代理模式

一说到代理,很多人都会立马想到设计模型中的代理模式,通过持有被代理对象并继承被代理对象的类便可以实现代理。假设我们要给ServiceA代理日志功能,就需要声明并实现日志代理类。如果要给ServiceA代理事务功能,就又需要声明并实现事务代理类。这时如何整合日志和事务代理功能就是一个问题了。其次,假设ServiceA当中有100个方法,都需要手工加上100次日志代码。再其次,假设ServiceA、ServiceB、ServiceC都需要代理日志的话,还得针对这三个Service生成不同的代理类。
我们可以看到静态代理的局限性:

  • 难以整合不同的代理类去代理同一个对象。
  • 难以在类内部的各个方法复用代理逻辑。
  • 难以在不同的类之间复用代理逻辑。
  • 需要大量的代理类才能满足我们的庞大的业务需求。

而动态代理是如何灵活的解决这些问题的呢?

JDK动态代理

首先我们先使用动态代理最基础的用法,不涉及Spring框架的最原始方法。

先声明一个HelloService接口:

public interface HelloService {
    void hello();
}

HelloService的实现类:

public class HelloServiceImpl implements HelloService {
    @Override
    public void hello() {
        System.out.println("hello!");
    }
}

2019-10-11 0 评论 298 浏览
阅读全文
Spring AOP详解 有更新!

情景案例

小明辛苦忙了一整年终于完成了包含300个接口的业务系统项目。项目圆满上线并稳定运行了一段时间了。突然有一天总监说,对于会造成数据变化的所有接口,我们必须记录用户的操作日志。然后小明就吭哧吭哧给其中150个接口,挨个加上日志代码,累得真够呛。

过了一阵子总监又说,所有变化很少的数据全部都加上缓存,缓存涉及到刷新缓存、获取缓存、删除缓存的问题。于是乎,小明就又吭哧吭哧地给其中的100个接口加上缓存相关的代码。

又过了一阵子总监说,所有涉及充值退款费用相关的接口,需要生成发票单存入数据库。这时候小明又需要吭哧吭哧给涉及到的50个接口,挨个加上发票存储操作。

小明天天加班也没在工期内完成任务,并且原本的业务代码已经变得臃肿不堪了。

原本的代码:

/**
 * 业务方法
 */
public static void method() {

    // 业务操作
    doBusiness();

}

经过硬编码添加各种非业务性代码后的业务代码:

/**
 * 业务方法
 */
public static void method() {
    // 日志操作
    doLog();
    // 业务操作
    doBusiness();
    // 缓存操作
    doLog();
    // 发票操作
    doReceipt();

}

读者应该能明显感受到在没有AOP代理的情况下的缺点

  1. 业务代码和非业务代码混杂在一起,原本清晰的业务流程淹没在与业务不相关的代码中。
  2. 增加非业务性的功能时,都需要手工硬编码去实现,费时费力。
  3. 代码变得不好维护,一是代码耦合度高,二是需要通过硬编码的方式去拓展或者修改功能。

2019-10-07 0 评论 429 浏览
阅读全文

思考

Spring已经占据我们Java开发框架中的半壁江山了,从一开始工作我们就在使用Spring。但是到底为什么要用Spring,可能很多人都没有去思考过这个问题?许多人可能也疲于应对需求,无暇思考这种看似理所当然的问题。那今天,我们就好好来讨论一下究竟为什么要使用Spring IOC?

逆向思考

假设在最初没有Spring IOC这种框架的时候,我们采用传统MVC的方式来开发一段常见的用户逻辑。

用户DAO

public class UserDAO {

    private String database;

    public UserDAO(String dataBase) {
        this.database = dataBase;
    }
    public void doSomething() {
        System.out.println("保存用户!");
    }

}

用户Service

public class UserService {

    private UserDAO dao;

    public UserService(UserDAO dao) {
        this.dao = dao;
    }
    public void doSomething() {
        dao.doSomething();
    }

}

用户Controller

public class Controller {

    public UserService service;

    public Controller(UserService userService) {
        this.service = userService;
    }

    public void doSomething() {
        service.doSomething();
    }

}

2019-09-11 3 评论 987 浏览
阅读全文

废话不多说,我们先做一个傻瓜版的IOC demo作为例子

自定义的Bean定义

class MyBeanDefinition{

    public String id;
    public String className;
    public String value;

    public MyBeanDefinition(String id, String className, String value) {
        this.id = id;
        this.className = className;
        this.value = value;
    }

}

2019-09-10 0 评论 334 浏览
阅读全文