手动使用cglib代理(了解)

这个你学会了将来也没啥机会用,将来你要玩AOP,学会了也只是得瑟一下说来手写一个AOP,你看看我是否厉害,

你不明白太阳是7个颜色构成的,也不影响你晒太阳,然后呢,AOP这个代码呢,咱们再来一个UserServiceProxyFactory2,

刚才在这里面的话,这叫观光代码,之动态代理,咱们这个2呢,更是观光代码了,之cglib代理,接下来看一下,这个代理

类当中,方法都一样的,也是一个获得UserService代理对象的方法,然后只是咱们用cglib代理来做,cglib作为第三方代理的话,

理论上是要导包的,但是因为咱们的Spring,整合了cglib代理,所以cglib包,已经在Spring包中了,这里直接写一个,叫做

Enhancer,cglib玩的话,核心叫做Enhancer,直接new就可以了,然后Enhancer拿出来以后,接下来的话你得告诉他,这哥们是

给你产生代理对象的,帮我们生成代理对象的,那你拿着这个类,你得告诉他,你得告诉他目标对象是谁啊,setSuperClass,

告诉他目标对象是谁,人家要你给的是一个class,咱们说了,cglib主要是对类进行继承代理,所以你得告诉他爹是谁,

那要对谁进行代理啊,对UserService进行代理,UserServiceImpl这个是代理的对象,是不是这个意思,然后en.setCallback,

这个生成代理你想干啥,这个是设置对谁进行代理,下面是代理要做什么,这个cglib是这个玩法,咱们实现Callback,咱们找一下

是哪一个Callback,这个Callback看一下,找到子类MethodInterceptor,然后这个东西是Callback接口的子类,发现子类太多了,

然后他在这里面传了四个参数,这四个参数,这个是arg,这是被代理的方法method,原始的方法,这是被代理的对象obj,

目的跟之前一样,首先要调用原有的方法,在原有方法执行之前打开事务,调用原有方法之后,提交事务,然后这个返回值,

然后接下来的话咱们看一下,用原有的方法怎么来调,原有的方法可以使用MethodProxy,点invokeProxy,这东西没啥道理,

然后方法的参数就是他,把这个参数拿过来,然后前面要给他一个对象,这个对象的话我看看,proxyObj,把这个返回值接收一下,

然后这个叫returnValue吧,然后把这个返回,这样的话原有的方法就调用了,接下来打开事务这块,打印一下打印事务,

然后提交事务这块打印一下提交事务,然后en点create方法,这个叫创建代理对象,然后接收一下,UserService接收,

这个代理对象不就是UserService接口的子类吗,然后return us,这样的话就返回代理对象
package com.learn.c_proxy;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import com.learn.service.UserService;
import com.learn.service.UserServiceImpl;

/**
 * 观光代码=>cglib代理
 * @author Leon.Sun
 *
 */
public class UserServiceProxyFactory2 implements MethodInterceptor {
	

	public UserService getUserServiceProxy() {

		/**
		 * 帮我们生成代理对象
		 */
		Enhancer en = new Enhancer();
		
		/**
		 * 设置对谁进行代理
		 */
		en.setSuperclass(UserServiceImpl.class);
		
		/**
		 * 代理要做什么
		 */
		en.setCallback(this);
		
		/**
		 * 创建代理对象
		 */
		UserService us = (UserService) en.create();
		
		return us;
	}

	@Override
	public Object intercept(Object proxyObj, Method method, Object[] arg, 
			MethodProxy methodProxy) throws Throwable {
		/**
		 * 打开事务
		 */
		System.out.println("打印事务!");
		
		/**
		 * 调用原有方法
		 */
		Object returnValue = methodProxy.invokeSuper(proxyObj, arg);
		
		/**
		 * 提交事务
		 */
		System.out.println("提交事务!");
		
		return returnValue;
	}
}
咱们就是new一个UserServiceProxyFactory2,然后这个参数,然后这块的话是2,调回方法,返回代理对象,

执行一下看行不行
	@Test
	public void fun2() {
		
		UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();
		
		UserService usProxy = factory.getUserServiceProxy();
		
		usProxy.save();
			
	}
打印事务!
保存用户!
提交事务!
所以你看看,咱们使用cglib代理,也是生成代理对象,为我们的目标方法进行一个增强,

之前打开事务,之后提交事务,然后接下来你得再看一下,咱们生成的UserProxy对象,给你们看看原理,

生成proxy对象,instanceof,判断他是不是UserServiceImpl类型的,能看到是啥意思不,这个是判断代理对象,

是否是被代理对象类型,咱们说这个cglib的特点,代理对象继承了被代理对象,所以这个代理对象实际上是,代理

对象实际上被代理对象的子类,那你子类判断是否属于父类,那是true还是false,所以执行的话是true
	@Test
	public void fun2() {
		
		UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();
		
		UserService usProxy = factory.getUserServiceProxy();
		
		usProxy.save();
		
		/**
		 * 判断代理对象是否属于被代理对象类型
		 */
		System.out.println(usProxy instanceof UserServiceImpl);
			
	}
打印事务!
保存用户!
提交事务!
true
通过这个打印就说明了,咱们的代理对象继承了被代理对象,所以结果是true,然后再看,这个实现可以拿到

上面来做一个,上面咱们这个是动态代理的,动态代理中代理对象和被代理对象之间有什么关系,有什么关系,

他们之间的关系,其实说实话,没关系,他们其实仅仅是实现了同一个接口,所以这个判断结果是什么,是false,

看到效果了吗
	/**
	 * 动态代理
	 */
	@Test
	public void fun1() {
		UserService us = new UserServiceImpl();
		
		UserServiceProxyFactory factory = new UserServiceProxyFactory(us);
		
		UserService usProxy = factory.getUserServiceProxy();
		
		usProxy.save();
		
		/**
		 * false
		 */
		System.out.println(usProxy instanceof UserServiceImpl);
			
	}
打开事务
保存用户!
提交事务
false
是代理对象和被代理对象实现了相同的接口,所以代理对象和被代理对象之间,你要是说有关系,

那也是兄弟的关系,同一个爹,实现相同的接口,这个代理对象和被代理对象,没有这个继承关系,

看明白啥意思吧,这个知识点要你们掌握的,这个叫观光代码,要求你们掌握的是,知道这两种代理

他们的特点,动态代理是接口,而cglib是对被代理对象进行继承,这是你们要知道的概念

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值