spring的代理模式

1、何为代理模式

        如何实现在不修改源码的基础上实现代码功能的增强呢?spring为我们提供了代理模式。所谓的代理模式通俗来说就是一个中介,它给某一个对象提供一个代理对象,并由代理对象控制原对象的引用,从而实现在不修改源码的基础上实现代码功能的增强。

2、分类

        按照代理创建的时期进行分类,可以分为两类:静态代理、动态代理。

        静态代理的代理类=原始类+增强(额外功能)+和原始类实现同一个接口,即基于接口的代理。

        动态代理又分为jdk动态代理,其也是基于接口的代理;cglib的动态代理。

三、实验的代码:

新建实体类User.class

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String username;
    private String password;
}

其中使用lombok实现实体类的所有方法。

新建接口UserService

public interface UserService {
    boolean addUser(User user);
    Integer delete(Integer id);
}

新建实现类UserServiceImpl

public class UserServiceImpl implements UserService{
    @Override
    public boolean addUser(User user) {
        System.out.println("service核心业务:添加用户对象"+user);
        return false;
    }

    @Override
    public Integer delete(Integer id) {
        System.out.println("service核心业务:一个用户对象被删除,id = "+id);
        return null;
    }
}

编写测试代码test01

@org.junit.Test

    public void test01(){
        UserServiceImpl userService = new UserServiceImpl();
        User user = User.builder().username("tom").password("root").build();
        userService.addUser(user);
    }

测试结果为:

现在添加日志打印功能

public class UserServiceImplStaticProxy implements UserService {

    private UserServiceImpl userService = new UserServiceImpl();
    @Override
    public boolean addUser(User user) {
//        添加日志的打印功能
        System.out.println("-----------log-----------");
//        调用原始类中添加用户的方法   核心业务
        userService.addUser(user);
        return false;
    }

    @Override
    public Integer delete(Integer id) {
        return null;
    }
}

重新编写两个测试代码test01

@org.junit.Test
    public void test02(){
        UserServiceImplStaticProxy userService = new UserServiceImplStaticProxy();
        User user = User.builder().username("jason").password("123").build();
        userService.addUser(user);
    }

测试结果为:

可以看到日志功能已经添加成功

 接下来看基于jdk的动态代理

@org.junit.Test
    public void test03(){//基于jdk的动态代理
//        原始类
        UserServiceImpl userService = new UserServiceImpl();
        /**
         * ClassLoader:类加载器  java程序执行  编写源码 .java->编译 .class ---类加载器---  -> jvm 执行
         *              jvm虚拟机会针对每一个class文件  分配一个ClassLoader
         *      作用:
         *          1、加载class文件到jvm虚拟机
         *          2、生成该文件对应的Class对象(类对象),从而创建实体类对象
         *
         *      代理类不会被分配类加载器,但是可以借用其他类的加载器,实现程序的运行
         *
         * interface:原始类实现的接口
         * invocationHandler:额外的功能
         */

//        业务增强的逻辑代码
        InvocationHandler invocationHandler = new InvocationHandler() {
            /**
             * Object proxy:代表生成的代理对象
             * Method method:原始类中被调用的方法
             * Object[] args:调用方法的参数列表
             * 返回值 Object:原始类方法的返回值
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //添加日志的打印功能
                System.out.println("------jdk log-----");
                System.out.println("原始类中被调用方法名子:"+method.getName());
                System.out.println("调用方法的参数列表是:"+ Arrays.toString(args));
                //调用原始类的方法
                Object invoke = method.invoke(userService, args);
                return invoke;
            }
        };
//        创建动态代理对象 userService  $proxy
        UserService userService1 = (UserService)Proxy.newProxyInstance(Test.class.getClassLoader(), userService.getClass().getInterfaces(), invocationHandler);
        User user = User.builder().password("123").username("jason").build();
//        invoke
        userService.addUser(user);
    }

最后再看基于cglib的动态代理

@org.junit.Test
    public void test04(){//基于cglib的动态代理,基于父子关系创建代理对象

        UserServiceImpl2 userServiceImpl2 = new UserServiceImpl2();
        Enhancer enhancer = new Enhancer();
//        设置相关参数
        enhancer.setClassLoader(this.getClass().getClassLoader());
        enhancer.setSuperclass(userServiceImpl2.getClass());
//        Callback增强的业务,类似jdk中的invoke方法
        MethodInterceptor methodInterceptor = new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

                System.out.println("-----------cglib log-------------");
                Object invoke = method.invoke(userServiceImpl2,objects);
                return invoke;
            }
        };
        enhancer.setCallback(methodInterceptor);

        //通过enhancer创建代理对象
        UserServiceImpl2 userServiceImpl21 = (UserServiceImpl2)enhancer.create();
        User jason = User.builder().username("jason").password("123").build();
        userServiceImpl21.addUser(jason);
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值