什么是代理
- 代理是一种设计模式,提供了对目标对象另外的访问方式。(用户不需要直接访问目标对象,只需要接触代理对象就能实现访问)
![什么是代理](https://i-blog.csdnimg.cn/direct/e2a13dd1ff634e44ab79a8276dc65767.jpeg#pic_center)
代理的好处
- 目标对象可以被间接访问
- 可以在目标对象实现的基础上实现额外的功能(除了目标对象提供的方法外,代理可以额外提供一些实用的方法),即扩展目标对象的功能
- 不会轻易修改原有代码,如果需要修改需求,可以通过代理去扩展
实现代理的方式
![代理](https://i-blog.csdnimg.cn/direct/99b566ebc596488293db71edba65f1c0.jpeg#pic_center)
- 静态代理只能完成对固定类的代理,动态代理的底层通过反射实现,可以完成任意类的代理(静态代理也可以通过接口或继承实现)
- 实现JDK动态代理主要依赖接口实现
- 需要第三方jar包支撑来实现的功能,一般通过继承来实现
![代理实现](https://i-blog.csdnimg.cn/direct/cd6c385c057144d98e50c2f7dd2bbd26.jpeg#pic_center)
代码示例
静态代理(通过接口实现)
public interface ByShop {
void clothes(String size);
}
public class Factory implements ByShop {
@Override
public void clothes(String size) {
System.out.println("已经为您制作了" + size + "大小尺寸的衣服!");
}
}
public class Proxy implements ByShop {
public Factory factory;
public Proxy(Factory factory) {
this.factory = factory;
}
@Override
public void clothes(String size) {
frontService();
factory.clothes(size);
endService();
}
public void frontService() {
System.out.println("根据您的需求进行产品研发!");
}
public void endService() {
System.out.println("产品已交付您,后续有问题随时联系!");
}
}
public class User {
public static void main(String[] args) {
Factory factory = new Factory();
Proxy proxy = new Proxy(factory);
proxy.clothes("xxl");
}
}
动态代理(接口实现)
public class Company implements InvocationHandler {
private Object factory;
public Object getFactory() {
return factory;
}
public void setFactory(Object factory) {
this.factory = factory;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = method.invoke(factory, args);
return obj;
}
public Object getProxyInstance() {
return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
}
}
public class User {
ClothesFactory clothesFactory = new ClothesFactory();
ShootsFactory shootsFactory = new ShootsFactory();
Company company = new Company();
company.setFactory(clothesFactory);
ByClothes good1 = (ByClothes)company.getProxyInstance();
good1.clothes("xxl");
}