前言
代理模式:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。代理模式分为静态代理、动态代理。
动态代理 :分为jdk动态代理和cglib动态代理。动态代理会在编译生成.class文件时候执行,会多一个代理类的文件。spring框架会自己选择执行哪种代理,除非你强制选择cglib动态代理
jdk和cglib动态代理差异 :
- jdk动态代理是Java原生的不需要引入第三方jar
- jdk动态代理委托类对象必须要实现接口才行
- cglib动态代理是第三方的要引入第三方jar
- cglib动态代理委托类不需要实现接口
JDK动态代理
1. JDK动态代理介绍
JDK动态代理Java自带的动态代理,要求传入classloader,接口数组和InvocationHandler
- java.lang.reflect.Proxy:生成动态代理类和对象;
- java.lang.reflect.InvocationHandler(处理器接口):可以通过invoke方法实现
对真实角色的代理访问。每次通过 Proxy 生成的代理类对象都要指定对应的处理器对象。
2.JDK动态代理步骤参考:
- 创建一个实现接口InvocationHandler的类,它必须实现invoke方法(可以匿名内部类实现)
- 创建被代理的类以及接口
- 通过Proxy的静态方法 newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理
- 通过代理调用方法
3. Jdk动态代理通用工具类
/**
* @author
*
*
* 代理对象工厂:生成代理对象的
*/
public class ProxyFactory {
private ProxyFactory(){
}
private static ProxyFactory proxyFactory = new ProxyFactory();
public static ProxyFactory getInstance() {
return proxyFactory;
}
/**
* Jdk动态代理
* @param obj 委托对象
* @return 代理对象
*/
public Object getJdkProxy(Object obj) {
// 获取代理对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try{
// 开启事务(关闭事务的自动提交)
// transactionManager.beginTransaction();
System.out.println("逻辑增强之开启事务");
//调用方法的时候执行代理类的方法
result = method.invoke(obj,args);
// 提交事务
System.out.println("逻辑增强之提交事务");
// transactionManager.commit();
}catch (Exception e) {
e.printStackTrace();
// 回滚事务
// transactionManager.rollback();
System.out.println("逻辑增强之回滚事务");
// 抛出异常便于上层捕获
throw e;
}
return result;
}
});
}
}
4. Jdk动态代理之具体实现
/**
* 接口
*/
public interface TransferService {
void transfer(String fromCardNo,String toCardNo,int money) throws Exception;
}
//实现类方法
public void transfer(String fromCardNo, String toCardNo, int money) throws Exception {
System.out.println("执行转账")
//出现异常 int c = 1/0
System.out.println("执行收账")
}
//调用代理执行
//获取要代理的委托对象
TransferService transferService1 = new TransferServiceImpl();
//获取代理对象工厂对象
ProxyFactory proxyFactory1 = ProxyFactory.getInstance();
//获取具体的代理对象
TransferService jdkProxy = (TransferService)proxyFactory1.getJdkProxy(transferService1);
//执行对象具有的方法
jdkProxy.transfer("1","2",3);
原方法执行
执行转账
执行收账
jdk动态代理类执行方法
逻辑增强之开启事务
执行转账
执行收账
逻辑增强之提交事务(出现异常时会:逻辑增强之回滚事务 )
cglib动态代理
1. cglib 动态代理介绍
cgib动态代理CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。并不是jdk自带的功能。
2. 引入外部依赖
<!--引入cglib依赖包-->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_2</version>
</dependency>
</dependencies>
3. cglib动态代理通用工具类
/**
* @author
*
*
* 代理对象工厂:生成代理对象的
*/
public class ProxyFactory {
private ProxyFactory(){
}
private static ProxyFactory proxyFactory = new ProxyFactory();
public static ProxyFactory getInstance() {
return proxyFactory;
}
/**
* 使用cglib动态代理生成代理对象
* @param obj 委托对象
* @return
*/
public Object getCglibProxy(Object obj) {
return Enhancer.create(obj.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object result = null;
try{
// 开启事务(关闭事务的自动提交)
// transactionManager.beginTransaction();
System.out.println("逻辑增强之开启事务");
//调用方法的时候执行代理类的方法
result = method.invoke(obj,args);
// 提交事务
System.out.println("逻辑增强之提交事务");
// transactionManager.commit();
}catch (Exception e) {
e.printStackTrace();
// 回滚事务
// transactionManager.rollback();
System.out.println("逻辑增强之回滚事务");
// 抛出异常便于上层捕获
throw e;
}
return result;
}
});
}
}
4. cglib动态代理之具体实现
/**
* 接口同一个
*/
public interface TransferService {
void transfer(String fromCardNo,String toCardNo,int money) throws Exception;
}
//实现类方法同一个
public void transfer(String fromCardNo, String toCardNo, int money) throws Exception {
System.out.println("执行转账")
//出现异常 int c = 1/0
System.out.println("执行收账")
}
//调用代理执行
//获取要代理的委托对象
TransferService transferService2 = new TransferServiceImpl();
//获取代理对象工厂对象
ProxyFactory proxyFactory2 = ProxyFactory.getInstance();
//获取具体的代理对象
TransferService cglibProxy = (TransferService)proxyFactory2.getCglibProxy(transferService2);
//执行对象具有的方法
cglibProxy.transfer("1","2",3);
原方法执行
执行转账
执行收账
cglib动态代理类执行方法
逻辑增强之开启事务
执行转账
执行收账
逻辑增强之提交事务(出现异常时会:逻辑增强之回滚事务 )