代理模式
代理模式
静态代理
优点
业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。代理使客户端不需要知道实现类是什么,怎么做的,而客户端只需知道代理即可(解耦合)
缺点
代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。
接口
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();
}
}
.
浙公网安备 33010602011771号