什么是代理:代理是一种设计模式 ,给目标对象提供一个代理对象,并且由代理对象控制对目标对象的引用
代理的目的:①:通过代理对象的方式间接的访问目标对象,防止直接访问目标对象给系统带来不必要的复杂性②:通过代理业务对原有业务进行增强
代理分类:静态代理,基于jdk(接口)的动态代理,基于CGLLIB(父类)的动态代理
一、静态代理
1.定义接口 相当于工厂的地址
public interface ByClothes {
void clothes(String size);
}
2.定义目标对象---制造衣服的工厂---实现接口
public class ClothesFactory implements ByClothes {
public void clothes(String size) {
System.out.println("已经为您制作好了一整套size为"+size+"的衣服。。。。。。。。");
}
}
3. 定义代理对象---也需要实现接口
public class proxy implements ByClothes {
//被包含的真是对象
public ClothesFactory factory;
public proxy(ClothesFactory factory) {
// TODO Auto-generated constructor stub
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("为您提供一条龙的包办服务");
}
}
4.测试类 相当于顾客
public class Test {
public static void main(String[] args) {
ClothesFactory clothesFactory = new ClothesFactory();
proxy proxy = new proxy(clothesFactory);
proxy.clothes("XXl");
}
}
静态代理:违反了开闭原则;因为如果有新需求,对于静态代理需要修改源代码;
二、动态代理
可以代购很多商品
1.定义接口
public interface ByShoot {
void byShoot(String size);
}
2.新建工厂 实现接口
public class ShootFactory implements ByShoot{
public void byShoot(String size) {
System.out.println("已经为您生产出了尺码为"+size+"的鞋子");
}
}
3.新建代购 实现接口
public class LisiFactory implements InvocationHandler {
// 被代理的对象
private Object factory ;
public Object getFactory() {
return factory;
}
public void setFactory(Object factory) {
this.factory = factory;
}
//ssm: Spring SpringMVC mybitys
//Spring:AOP IOC +....
//AOP:代理 (面向切面的编程)
// 通过代理对象对方法进行增强
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
FrontService();
Object retObject = method.invoke(factory, args); //这里用了反射的思想,因为我们不知道调用的是那个工厂的那个方法
endService();
return null;
}
// 前置服务
public void FrontService() {
System.out.println("根据您的需求进行市场调研");
}
// 后置服务
public void endService() {
System.out.println("为您提供一条龙的包办服务");
}
//调度员工
/**
* 1 新建一名员工
* 2.告诉员工工厂地址
* this:绑定
* @return
*/
public Object getProxyInstance() {
// TODO Auto-generated method stub
return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
}
}
4.新建测试类---顾客
public class Test {
public static void main(String[] args) {
ClothesFactory clothesFactory = new ClothesFactory();
ShootFactory shootFactory = new ShootFactory();
LisiFactory lisiFactory = new LisiFactory();
lisiFactory.setFactory(shootFactory);
ByShoot yuangong1 = (ByShoot) lisiFactory.getProxyInstance();
yuangong1.byShoot("42");
lisiFactory.setFactory(clothesFactory);
ByClothes yuangong = (ByClothes) lisiFactory.getProxyInstance();
yuangong.clothes("XXL");
}
}
通过动态代理我们在测试类中利用多态对工厂等进行调用,并不用改变之前的代码,需要业务增强时,只需要创建新工厂即可。