代理模式通常分为静态代理和动态代理两种,用于功能增强。
静态代理:
1.代理类和目标类都需实现同一接口。
2.代理类中需有目标类实例。
3.代理类实现接口方法,对目标类根据实际情况进行增强,也就是执行一定逻辑,并调用目标类方法。
这样就会导致接口每增加一个方法,则代理类和目标类都需实现该方法。
public interface StaticSourceable { public void doMethod(); } public class StaticSource implements StaticSourceable { public void doMethod() { System.out.println("业务处理。。。"); } } public class StaticProxy implements StaticSourceable { StaticSource source; public StaticProxy() { // 在代理类的无参构造器中创建目标对象 this.source = new StaticSource(); } // 代理类对StaticSource的doMethod方法做了增强 public void doMethod() { before(); try { source.doMethod(); } catch (Exception e) { exception(); } after(); } public void before() { System.out.println("进入方法。。。"); } public void after() { System.out.println("执行结束。。。"); } public void exception() { System.out.println("出现异常。。。"); } public static void main(String[] args) { StaticSourceable source = new StaticProxy(); source.doMethod(); } }
动态代理又分为JDK动态代理和CGLib动态代理。
JDK动态代理:基于接口的代理方式。
1.目标类实现目标类接口。
2.代理类实现 java.lang.reflect.InvocationHandler 接口。
3.代理类中需定义Object目标对象,可通过构造方式或set方式赋值。
4.代理类需实现接口中的 Object invoke(Object proxy, Method method, Object[] args) 方法。
5.代理类提供返回目标类实例的方法,如getProxy(),其是通过直接调用 java.lang.reflect.Proxy 的静态方法 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 来获取增强后的实例,这是通过反射完成的。
// 目标类接口 public interface IMyJDKTarget { void doMethod(); } // 目标类 public class MyJDKTargetImpl implements IMyJDKTarget { public void doMethod() { System.out.println("业务处理。。。"); } } // 代理类 public class JDKProxyFactory implements InvocationHandler { // 目标对象 private Object target; public JDKProxyFactory(Object target) { super(); this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); // 调用目标对象方法 Object object = method.invoke(target, args); after(); return object; } public Object getProxy() { // 直接调用java.lang.reflect.Proxy的静态方法newProxyInstance return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public void before() { System.out.println("进入方法。。。"); } public void after() { System.out.println("执行结束。。。"); } public static void main(String[] args) { IMyJDKTarget target = (IMyJDKTarget) new JDKProxyFactory(new MyJDKTargetImpl()).getProxy(); target.doMethod(); } }
CGLib动态代理:基于类的代理方式。
1.目标类不需要实现接口。
2.代理类实现 net.sf.cglib.proxy.MethodInterceptor接口。
3.代理类中需定义Object目标对象,可通过构造方式或set方式赋值。
4.代理类需实现接口中的 Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)方法。
5.代理类中提供返回增强后的目标对象方法,如getProxy(),其是通过创建增强器Enhancer,设置需要增强的目标对象和回调方法后,调用create()方法来获取到增强后的实例对象。
// 目标类(不需要接口) public class MyCgLibTarget { public void doMethod() { System.out.println("业务处理。。。"); } } // 代理类 public class CgLibProxyFactory implements MethodInterceptor { // 目标对象 private Object target; public CgLibProxyFactory(Object target) { super(); this.target = target; } public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { before(); // 调用目标对象方法 Object object = proxy.invoke(target, args); after(); return object; } public Object getProxy() { // 创建增强器 Enhancer enhancer = new Enhancer(); // 设置需要增强的类的类对象 enhancer.setSuperclass(target.getClass()); // 设置回调函数 enhancer.setCallback(this); // 获取增强之后的代理对象 return enhancer.create(); } public void before() { System.out.println("进入方法。。。"); } public void after() { System.out.println("执行结束。。。"); } public static void main(String[] args) { MyCgLibTarget target = (MyCgLibTarget) new CgLibProxyFactory(new MyCgLibTarget()).getProxy(); target.doMethod(); } }
原文:https://www.cnblogs.com/scorpio-cat/p/12715222.html