1.代理模式的简介
1简介:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。相当于现在手机店,手机店去工厂进货,卖给我们,进行前期的手机宣传和后期的售后服务
2.作用:
实现对目标对象原有的功能增强,即扩展目标对象的功能方法,并且不会修改原有代码
3.分类:
1) 静态代理,在运行前,通过编写代码的方式生成代理类
2) 动态代理,在运行后,通过反射机制生成代理类
静态代理
1)代理者和被代理者都实现相同的接口
2)代理者包含被代理者的对象
3)创建代理对象时传入被代理对象
4)代理者执行方法时,会调用被代理者的方法,同时扩展新的功能
package com.hk.service;
/**
* 定义一个接口(一类人要做的事情)
* @author 浪丶荡
*
*/
public interface ISomeService {
//打官司
public String Litigate();
//吃饭
public String eat();
}
————————————————
```java
package com.hk.service;
/**
* 目标类
* @author 浪丶荡
*
*/
public class ISomeServiceImp implements ISomeService {
@Override
public String Litigate() {
return "自己打官司,输了";
}
@Override
public String eat() {
return "自己吃饭";
}
}
——
```java
package com.hk.service;
/**
* 目标类
* @author 浪丶荡
*
*/
public class ISomeServiceImp implements ISomeService {
@Override
public String Litigate() {
return "自己打官司,输了";
}
@Override
public String eat() {
return "自己吃饭";
}
}
```java
package com.hk.service;
/**
* 代理类
* @author 浪丶荡
*
*/
public class ServiceProxy implements ISomeService {
//客户
private ISomeService target;
public ServiceProxy() {
}
//联系客户接受任务,为谁打官司
public ServiceProxy(ISomeService target) {
this.target = target;
}
//帮客户打官司
@Override
public String Litigate() {
return "律师打官司,赢了";
}
//吃饭就让客户自己吃吧
@Override
public String eat() {
return target.eat();
}
}
————————————————
```java
package com.hk.test;
import com.hk.service.ISomeService;
import com.hk.service.ISomeServiceImp;
import com.hk.service.ServiceProxy;
public class MyTest {
public static void main(String[] args) {
//有money人张三
ISomeService zhangsan = new ISomeServiceImp();
//屌丝李四
ISomeService lisi = new ISomeServiceImp();
//张三请的律师打官司,饭自己吃
ISomeService sp = new ServiceProxy(zhangsan);
System.out.println("zhangsan"+sp.Litigate()+"-----"+sp.eat());
//苦逼的李四自己打官司,自己吃饭
System.out.println("lisi"+lisi.Litigate()+"-----"+lisi.eat());
}
}
zhangsan律师打官司,赢了-----自己吃饭
lisi自己打官司,输了-----自己吃饭
静态代理:一个代理类只能代理一种业务,如果有多种业务,就必须创建大量的代理类。
动态代理
JDK动态代理
JDK自带的,前提是:被代理类必须实现过接口。
/**
* 工厂的JDK动态代理
*/
public class JDKFactoryProxy implements InvocationHandler {
//被代理对象
private Object target;
/**
* 创建代理对象
* @param target 被代理对象
* @return 代理对象
*/
public Object createProxy(Object target){
this.target = target;
//创建代理对象 参数1:类加载器, 参数2:代理对象实现的接口,参数3:InvocationHandler的实现对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
/**
* 代理类的方法调用
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//功能扩展
System.out.println("商店帮忙打广告!!");
//调用被代理者方法
Object invoke = method.invoke(target, args);
System.out.println("商店帮忙做售后!!");
return invoke;
}
}
CGLib动态代理
需要引入CGLib依赖,它的原理是:通过反射+继承机制动态生成被代理类的子类,所以被代理类不能是final的。
/**
* CGLib动态代理
*/
public class CGlibFactoryProxy implements MethodInterceptor {
//被代理对象
private Object target;
public Object createProxy(Object target){
this.target = target;
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(this.target.getClass());
//设置方法回调MethodInterceptor实现
enhancer.setCallback(this);
//返回代理对象
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//扩展
System.out.println("CGLib商店打广告!");
//调用原来方法
Object invoke = method.invoke(target, objects);
System.out.println("CGLib商店做售后!");
return invoke;
}
}