动态代理是一种强大的编程思想,其核心在于运行时动态生成代理对象,动态代理的概念可以简单理解为,利用这一机制,在无代码侵入的条件下对原有的对象的方法进行功能添加。这种思想广泛应用于 AOP(面向切面编程)等场景。以下是对动态代理思想的深入解析:
一、动态思想
- 运行时生成:代理类和对象在程序运行时动态创建,而非编译期。
- 无侵入性:目标类无需实现特定接口或继承基类,代理逻辑可灵活配置。
二、代理思想
代理对象充当目标对象的 “中间人”,拦截对目标对象的访问,在执行目标方法前后添加额外逻辑(如日志、权限校验),而无需修改目标对象的代码。
三、实现方式(JDK动态代理方式)
下面是一个动态代理实现举例,该例子的目的是为在明星唱歌跳舞之前利用代理对其进行收费操作。
- 编写接口(动态代理对象的生成需要接口):
package Proxy_Instance; public interface StarService { void sing(String name); String dance(); }
- 编写明星类
package Proxy_Instance; public class Star implements StarService{ @Override public void sing(String name) { //参数为了演示代理对象创建方法中的中的args[] System.out.println("唱歌"+name); } @Override public String dance() { System.out.println("跳舞"); return "thanks"; } }
- 编写proxyUtils用于生成代理对象(封装起来提升类的复用性)
package Proxy_Instance; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyUtils { public static <T> T getProxy(T s) { //Proxy类提供了newProxyInstance方法可以new出代理对象 //参数一:类加载器 //参数二:要实现的接口类型 //参数三:匿名内部类中的Invoke是实际调用的方法,修改原始调用方法 T ss = (T) Proxy.newProxyInstance(ProxyUtils.class.getClassLoader() , s.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //参数一:要使用的代理对象 //参数二:原对象要使用的方法名 //参数三:方法的参数数组 //1.先执行自身的方法 String name = method.getName(); if(name.equals("sing")){ System.out.println("要唱歌了,先给钱20w"); }else if(name.equals("dance")){ System.out.println("要跳舞了,先给钱40w"); } //2.执行原始类的方法 Object result = method.invoke(s, args); return result; } }); return ss; } }
- Main方法()
package Proxy_Instance; public class run { public static void main(String[] args) { Star star = new Star(); StarService proxy_s = ProxyUtils.getProxy(star); proxy_s.sing("《夜曲》"); System.out.println(proxy_s.dance()); } }
- 运行结果