1.动态代理概念
- 动态代理通过创建一个代理类,该类实现了目标对象所实现的接口,从而在调用目标对象的方法时,可以插入自定义的逻辑。
通俗点说:
动态代理就是创建一个代理类,在代理类中调用被代理方法,并且在代理类进行一些加强操作。
举个例子:你的电脑桌上有显示器、键盘和鼠标。你想让你的电脑桌看起来好看一些,但是不想动原有的东西,你可以在桌面新添加摆件、氛围灯等等,这样就可以在不更改原有布局的情况下进行修饰桌面。
2.动态代理的应用场景
AOP(面向切面编程):
- 动态代理是AOP的核心实现机制之一,用于在方法执行前后织入切面逻辑。
日志记录:
- 在不修改原有代码的情况下,为方法调用添加日志记录功能。
权限校验:
- 在方法调用前进行权限校验,确保只有具有相应权限的用户才能执行该方法。
事务管理:
- 在方法调用前开启事务,调用后提交或回滚事务,确保数据的一致性。
远程服务调用:
- 通过代理对象实现远程服务调用的透明化,隐藏底层的通信细节。
3.动态代理案例
1.创建一个BeatMonsters接口
BeatMonsters 接口表示玩家能够进行的操作
package com.example.demo.proxyPratice;
public interface BeatMonsters {
/**
* 攻击怪物
* @return
*/
public String attack();
/**
* 防御
*/
public String def1();
}
2.创建一个Player 实体类实现 BeatMonsters接口
package com.example.demo.proxyPratice;
public class Player implements BeatMonsters{
private String name;
public Player(String name) {
this.name = name;
}
@Override
public String attack() {
System.out.println(this.name + "进行了攻击!");
return "";
}
@Override
public String def1() {
System.out.println(this.name + "开始防御!");
return "";
}
}
3.创建一个代理类,代理BeatMonsters 接口(重点)
package com.example.demo.proxyPratice;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class BeatMonsterProxy {
public static BeatMonsters createBeatMonsterProxy(Player player){
BeatMonsters proxy = (BeatMonsters) Proxy.newProxyInstance(BeatMonsterProxy.class.getClassLoader(),
new Class[]{BeatMonsters.class},
new InvocationHandler() {
/**
*
* @param proxy 代理实例,方法是在此实例上调用的
*
* @param method 与在代理实例上调用的接口方法对应的 {@code Method} 实例。
* 该 {@code Method} 对象的声明类将是声明该方法的接口,该接口可能是代理接口的超接口,
* 代理类通过继承获得该方法。
*
* @param args 包含传递给代理实例方法调用时的参数值的对象数组,
* 如果接口方法不接受参数,则为 {@code null}。
*
* @return 返回值
* @throws Throwable 抛出异常
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在被代理类之前执行
if ("attack".equals(method.getName())) {
System.out.println("玩家A装备了钻石剑!");
}
//被代理的方法执行
method.invoke(player,args);
//被代理类之后执行
if ("attack".equals(method.getName())) {
System.out.println("玩家A成功摧毁目标!");
} else {
System.out.println("没有受到伤害!");
}
return null;
}
});
return proxy;
}
}
4.调用代理类,实现想要的结果
package com.example.demo;
import com.example.demo.proxy.BigStar;
import com.example.demo.proxy.ProxyUtils;
import com.example.demo.proxy.Star;
import com.example.demo.proxyPratice.BeatMonsterProxy;
import com.example.demo.proxyPratice.BeatMonsters;
import com.example.demo.proxyPratice.Player;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
Player proxy = new Player("玩家ss");
BeatMonsters s = BeatMonsterProxy.createBeatMonsterProxy(proxy);
s.attack();
}
}
运行结果如下: