代理模式
静态代理
优点
业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。代理使客户端不需要知道实现类是什么,怎么做的,而客户端只需知道代理即可(解耦合)
缺点
代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。
接口
public interface Rent { void rent(); }
目标类
public class Host implements Rent{ @Override public void rent() { System.out.println("房屋出租"); } }
代理类
public class HostProxy implements Rent{ Host host; public HostProxy(Host host1){ this.host=host1; } @Override public void rent() { System.out.println("事务开始"); host.rent(); System.out.println("提交"); } }
客户
public class Client { public static void main(String[] args) { //静态代理 Host host = new Host(); HostProxy hostProxy = new HostProxy(host); hostProxy.rent(); } }
动态代理
jdk实现
需要被代理类实现有接口,然后通过Proxy类的newProxyInstance(ClassLoader loader,Class<?> interface,InvocationHandler h)方法创建
接口
public interface UserDao { int add(int a,int b); String paste(String str); }
被代理类:需要有实现接口
public class User implements UserDao{ @Override public int add(int a, int b) { return a+b; } @Override public String paste(String str) { return str; } }
代理类:需要传入被代理的对象
newProxyInstance方法参数解释ClassLoader loader,Class<?> interface,invocationHandler h
ClassLoader loader:获取类加载器
Class<?> interface:被代理类的接口类型,可以是一个数组
InvocationHandler h:具体执行代理的接口
public class UserProxy { private Object target; public UserProxy(Object obj){ target = obj; } public Object getProxy(){ return Proxy.newProxyInstance(UserDao.class.getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object invoke = null; System.out.println(method.getName()); if (method.getName().equals("add")){ System.out.println("开始增强"); invoke = method.invoke(target, args); System.out.println("方法执行完毕"); } return invoke; } }); } }
客户端调用以及结果输出
cglib实现
此方式不要求被代理类为接口的实现类,cglib基于继承被代理类实现的
需要先引入相关依赖
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.1</version> </dependency>
被代理的类
public class HelloCglib { public void sayHello() { System.out.println("CGLIB动态代理模式!"); } }
cglib代理类
public class CglibProxy implements MethodInterceptor { /** * 指定cglib代理模式的代理类 */ private final Object target; public CglibProxy(Object target) { this.target = target; } public Object getProxy() { Enhancer enhancer = new Enhancer(); //设置超类方法 enhancer.setSuperclass(this.target.getClass()); //设置一个回调方法,用来设置哪个类为代理类,this表示当前类为代理类 enhancer.setCallback(this); //创建代理对象 return enhancer.create(); } public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("CGLIB代理前"); Object object = proxy.invokeSuper(obj, args); System.out.println("CGLIB代理后"); return object; } }
客户端演示
public class HelloClient { public static void main(String[] args) { CglibProxy cglibProxy = new CglibProxy(new HelloCglib()); HelloCglib proxy = (HelloCglib) cglibProxy.getProxy(); proxy.sayHello(); } }
.
标签:target,Object,System,模式,代理,println,public From: https://www.cnblogs.com/happy12123/p/16816016.html