6.1静态代理
角色分析
- 抽象角色:一般会使用接口或者抽象类来解决
- 真实角色:需要被代理的角色
- 代理角色:代理真实角色,代理真实角色 后一般会在上面附加一些操作
- 客户:访问代理角色的人,而不需要再直接与真实角色交涉
编程步骤
- 接口(抽象角色)
public interface UserService {
public void add();
public void del();
public void upa();
public void sel();
}
- 实现类(真实角色)
//真实的对象
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加一条数据 ...");
}
@Override
public void del() {
System.out.println("删除一条数据 ...");
}
@Override
public void upa() {
System.out.println("修改一条数据 ...");
}
@Override
public void sel() {
System.out.println("查看数据 ...");
}
}
- 代理类(代理角色 )
public class UserServicePorxy implements UserService{
//找到需要代理的对象
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public void add() {
log("add");
userService.add();
}
@Override
public void del() {
log("del");
userService.del();
}
@Override
public void upa() {
log("upa");
userService.upa();
}
@Override
public void sel() {
log("sel");
userService.sel();
}
//打印日志方法
public void log(String meg){
System.out.println("使用了"+meg+"方法");
}
}
- 客户类(客户)
public class Client {
public static void main(String[] args) {
//需要代理的真实对象
UserService userService = new UserServiceImpl();
//找到代理人
UserServicePorxy userServicePorxy = new UserServicePorxy();
//进行代理交接
userServicePorxy.setUserService(userService);
//通过代理执行相关操作
userServicePorxy.add();
userServicePorxy.del();
}
}
优势
- 代理模式会使真实角色的功能变得更加的纯粹,不需要去 关注一些公共的业务功能
- 附加的一些公共的业务功能交给代理角色去实现,实现了业务的分工
- 公共业务发生扩展的时候,方便集中管理
缺点
- 每一个真实角色就需要一个代理角色,代码量会翻倍,降低开发的效率哦!
6.2动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是直接写出来的
- 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
- 基于接口-JDK动态代理(我们在这里使用)
- 基于类-cglib
- java字节码实现-javasist
- 需要了解两个类:Proxy代理,invocationhandler调用处理程序
优势
- 在静态代理的优势之上,另外有
- 一个动态代理类代理的是一个接口,一般就对应一类业务
- 一个动态代理类可以代理多个类,只要是实现了同一个接口
编程
接口(同上)
实现类(同上)
代理的工具类
//我们可以把这个类看作是一个工具类
//我们会用这个类自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的解接口
private Object target;
//动态获取需要被代理的接口
public void setTarget(Object target) {
this.target = target;}
//生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);}
@Override
//处理代理实例,并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target, args);
return result;}
//扩展业务功能
public void log(String msg){
System.out.println("执行了"+msg+"方法");}}
- 客户类
public class Client {
public static void main(String[] args) {
//真实角色是必须要有的
UserServiceImpl userService = new UserServiceImpl();
//现在没有代理类,我们需要使用那个工具类去生成获取代理
//生成工具
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//指定需要代理的真实角色到工具类中
pih.setTarget(userService);
//通过工具类生成并获取到代理类(这里需要注意返回的代理类应该是属于被代理的接口类型)
UserService proxy = (UserService)pih.getProxy();
//通过代理执行操作
proxy.del();
}
}