Java高级之动态代理
1、动态代理概念
动态代理作用: 不修改源码的基础上去增加一个对象的方法。 (增加某个对象的功能)
动态代理对象涉及角色:
被代理对象:
代理对象:
接口: 规定代理对象能够代理方法,能够使用的方法。
动态代理涉及API:
Proxy.newProxyInstance() 这个方法就是用于生成代理对象的。
ClassLoader loader, 类加载器, 这个参数不需要你们动脑袋,因为直接就使用当前类的Class对象的类加载器即可
Class<?>[] interfaces, 代理对象实现的接口数组
InvocationHandler 处理
invoke执行时机是什么? invoke方法的作用是什么?
代理对象的任意一个方法执行的时候,invoke方法都会执行一次。 把每一个方法的实现交给你。
动态代理的固定步骤:
1. 维护一个被代理对象。 因为动态代理模式的作用是增强,
2. 得到当前执行方法名, 判断是否为需要增强的方法
3. 如果是需要增强的方法,使用被代理对象执行原有的方法,然后写上自己的业务逻辑
4. 如果不是需要增强方法,直接使用被代理对象执行原有的方法即可。
5. 不管方法执行有没有返回值都使用一个变量去接收返回值,然后返回即可。
2、动态代理代码讲解
2.1 目录结构(Maven项目)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UiCfnoEB-1660032620440)(D:\download\record\blog\04-常用记录\java\Java高级之动态代理.assets\image-20220809160154953.png)]
AccountService
package com.onlyone.service;
public interface AccountService {
public void save();
public void update();
public void findById();
public void deleteById();
}
AccountServiceImpl
package com.onlyone.service.impl;
import com.onlyone.service.AccountService;
public class AccountServiceImpl implements AccountService {
@Override
public void save() {
System.out.println("保存账户....");
}
@Override
public void update() {
System.out.println("更新账户......");
}
@Override
public void findById() {
System.out.println("查找账户....");
}
@Override
public void deleteById() {
System.out.println("删除账户.....");
}
}
AccountProxyFactory
package com.onlyone.proxy;
import com.onlyone.service.AccountService;
import com.onlyone.service.impl.AccountServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
需求: 使用动态代理增强增、删、改这三个方法。 增删改方法执行的时候都需要开启事务与提交事务,但是只需要模拟即可。
动态代理的步骤:
1.维护一个被代理对象
2、获取当前执行方法,判断是否为增强的方法
3. 如果是增强的方法,就使用被代理对象执行,然后写上自己增强的业务逻辑代码
4. 如果不是需要增强的方法,直接使用被代理对象执行即可。
5. 不管方法是否有返回值都使用一个变量去接收然后返回。
*/
public class AccountProxyFactory {
public static AccountService getAccountServiceProxy(){
AccountService accountServiceProxy = (AccountService) Proxy.newProxyInstance(AccountProxyFactory.class.getClassLoader(), new Class[]{AccountService.class}, new InvocationHandler() {
//1.维护一个被代理对象
AccountService accountService = new AccountServiceImpl();
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//2、获取当前执行方法,判断是否为增强的方法
String methodName = method.getName();
//3. 如果是增强的方法,就使用被代理对象执行,然后写上自己增强的业务逻辑代码
Object result = null;
if(!"findById".equalsIgnoreCase(methodName)){
System.out.println("开启事务....");
result = method.invoke(accountService,args);
System.out.println("提交事务....");
}else{
//4. 如果不是需要增强的方法,直接使用被代理对象执行即可。
result= method.invoke(accountService,args);
}
//5. 不管方法是否有返回值都使用一个变量去接收然后返回。
return result;
}
});
return accountServiceProxy;
}
}
AppMain
package com.onlyone.main;
import com.onlyone.proxy.AccountProxyFactory;
import com.onlyone.service.AccountService;
/*
需求: 使用动态代理增强增、删、改这三个方法。 增删改方法执行的时候都需要开启事务与提交事务,但是只需要模拟即可。
*/
public class AppMain {
public static void main(String[] args) {
//1. 创建AccountService对象
AccountService accountServiceProxy = AccountProxyFactory.getAccountServiceProxy();
//2. 调用方法
// accountServiceProxy.save();
// accountServiceProxy.update();
accountServiceProxy.deleteById();
// accountServiceProxy.findById();
}
}
多看几遍动态代理的代码就能理解了