这个你学会了将来也没啥机会用,将来你要玩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是对被代理对象进行继承,这是你们要知道的概念