Spring入门知识 ———— 静态代理与动态代理的模式

一、引言

讲Spring AOP之前呢,大家先要了解代理,为啥? 因为AOP实现原理也是采用的动态代理,喔~~

如果之前没有接触过代理的小伙伴们,建议先去了解常用的设计模式中的代理模式。

二、场景需求

现在对用户进行增删改查的功能,代码如下:接口、以及实现类

需求:在增删改查的功能当中,需要加一个日志的功能。

public interface UserMange {

    void insertUser(String username, String password);

    String findUser(Integer id);

    void deleteUser(Integer id);

    void update(String username, String password, Integer id);
}
@Service
public class UserMangeImpl implements UserMange {

    public void insertUser(String username, String password) {
        System.out.println("----------UserMangeImpl.insertUser-----------");
    }

    public String findUser(Integer id) {
        System.out.println("----------UserMangeImpl.findUser-----------");
        return "张山";
    }

    public void deleteUser(Integer id) {
        System.out.println("----------UserMangeImpl.deleteUser-----------");
    }

    public void update(String username, String password, Integer id) {
        System.out.println("----------UserMangeImpl.update-----------");
    }
}

 

三、静态代理实现

为什么要使用代理? 其实用拦截器实现也是一样可以的,但是代理这种设计模式,小伙伴们是需要了解的。

针对这个需求,使用代理的好处是什么?

如果我们不使用代理,也不使用其它方式,那就只能在实现增删改查的方法中去加日志的功能。这样会对之前的核心代码造成影响,维护起来也特别麻烦。万一不需要这个日志功能了,还要去每个方法中去删除日志的代码。

使用代理之后,我们不需要去改动核心代码,而是在代理实现中添加日志的功能,最后调用最终实现增删改查功能即可。代理帮我们实现了添加日志的功能。

/**
 * 静态代理实现类
 */
@Service
public class UserMangeProxyImpl implements UserMange {

    /**
     * 原始实现对象引用进来
     */
    @Autowired
    private UserMangeImpl userMange;

    public void insertUser(String username, String password) {
        //插入日志功能
        insertLog();
        userMange.insertUser(username,password);
    }

    public String findUser(Integer id) {
        //插入日志功能
        insertLog();
        return userMange.findUser(id);
    }

    public void deleteUser(Integer id) {
        //插入日志功能
        insertLog();
        userMange.deleteUser(id);
    }

    public void update(String username, String password, Integer id) {
        //插入日志功能
        insertLog();
        userMange.update(username,password,id);
    }

    private void insertLog(){
        System.out.println("UserMangeProxyImpl.insertLog.......");
    }
}

测试测试一下:采用的是注解的形式装配Bean,配置文件我这边就不写出来了。在这里我们就不直接获取userManage对象了,而是获取的代理对象。

  public static void main(String[] args) {
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicaitonContext-noe.xml");
        UserMange userMange = (UserMange) beanFactory.getBean("userMangeProxyImpl");
        userMange.findUser(1);
    }
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
UserMangeProxyImpl.insertLog.......
----------UserMangeImpl.findUser-----------

Process finished with exit code 0

四、动态代理实现

静态代理实现的方式大家也都看到了,其实还是有点麻烦。怎么说呢?你看,每一个方法里面还是得加上添加日志的方法,虽然没有影响核心代码,但是还是不方便呀,得每个每个方法写。

那么,动态代理闪亮登场了!!!

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态代理实现日志记录
 */
public class InsertLogHandler implements InvocationHandler {

    private Object targerObject;

    public Object createInsertLogHandler(Object targerObject){
        this.targerObject = targerObject;

        //返回代理对象返回出去
        //这里参数的this,代表着这个类实现了InvocationHandler中的invoke方法
        return Proxy.newProxyInstance(targerObject.getClass().getClassLoader(),targerObject.getClass().getInterfaces(),this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //日志记录
        insertLog();

        //调用目标方法
        Object result = method.invoke(targerObject,args);
        return result;
    }

    private void insertLog(){
        System.out.println("InsertLogHandler.insertLog.......");
    }
}

使用动态代理后,只需要调用一次记录日志的方法,也便于维护。最后看下测试

public class Main {

    public static void main(String[] args) {
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicaitonContext-noe.xml");
        UserMangeImpl userMangeImpl = (UserMangeImpl)beanFactory.getBean("userMangeImpl");
        InsertLogHandler insertLogHandler = new InsertLogHandler();
        UserMange userMange = (UserMange)insertLogHandler.createInsertLogHandler(userMangeImpl);
        userMange.findUser(1);
    }
}
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
InsertLogHandler.insertLog.......
----------UserMangeImpl.findUser-----------

Process finished with exit code 0

 

今天就给大家讲了一下静态代理,和代理代理,明天就开始介绍Spring另外一个核心了。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页
实付 29.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值