静态代理
1、静态代理的角色分析:
抽象角色 ------ 一般使用接口或者抽象类来实现 。
真实角色 ------ 被代理角色 。
代理角色 ------ 代理真实角色 (代理真实角色后一般会做一些附属操作,比如房屋中介的附属操作是带人看房,收中 介费)
客户 ------ 使用代理角色来进行一些操作 。
2、代码实现:
项目结构如下:
Rent.java --- 抽象角色
package cn.myspring.staticproxy;
public interface Rent {
/**
* 房屋出租
*/
public void rent() ;
}
Host.java --- 真实角色
package cn.myspring.staticproxy;
/**
* 房东
*/
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房屋出租");
}
}
Proxy.java --- 代理角色
package cn.myspring.staticproxy;
/**
* 中介
*/
public class Proxy implements Rent {
private Host host;
public Proxy() {
}
public Proxy(Host host) {
super();
this.host = host;
}
public void setHost(Host host) {
this.host = host;
}
@Override
public void rent() {
seeHouse() ;
host.rent();
fare() ;
}
//看房
private void seeHouse() {
System.out.println("带房客看房");
}
//收中介费
private void fare() {
System.out.println("收取中介费");
}
}
Client.java --- 客户
package cn.myspring.staticproxy;
/**
* 租客
*/
public class Client {
public static void main(String[] args) {
Host host = new Host() ;
Proxy proxy = new Proxy(host) ;
proxy.rent() ;
}
}
控制台打印运行结果
3、使用静态代理的好处:
使得真实角色处理的业务更加纯粹,不在去关注一些公共的事情。
公共的业务由代理来完成 --- 实现业务的分工。
公共业务发生扩展时,更加集中和方便 。
缺点:
类多了 --- 多代理类,工作量变大,开发效率变低了。
解决静态代理的这些缺点的办法是,使用动态代理。
动态代理
分为两类:
1、基于接口的动态代理 -- JDK动态代理。
2、基于类的动态代理 -- cglib 。
现在大多使用javasist来生成动态代理。
3、jdk动态代理 --- Proxy类和invocationHandler接口
态代理是代理接口的,只要有接口就能代理
下面来看看具体的例子:
项目结构如图:
动态代理类ProxyInocationHandler代码:
package cn.my.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理类
*/
public class ProxyInocationHandler implements InvocationHandler {
private Object target;// 真实对象
public void setTarget(Object target) {
this.target = target;
}
/**
* 生成代理类
*
* @return
*/
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
this.target.getClass().getInterfaces(), this);
}
/**
* proxy:代理类 ; method:代理类的调用处理程序的方法对象
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
log(method.getName()) ;
// target是真实对象
Object result = method.invoke(target, args);
return result;
}
public void log(String methodName) {
System.out.println("执行" + methodName + "方法");
}
}
房屋出租接口--抽象角色 Rent代码:
package cn.my.dynamicproxy;
public interface Rent {
/**
* 出租房屋
*/
public void rent() ;
}
房屋拥有者--真实角色 Host代码:
package cn.my.dynamicproxy;
/**
* 房东
*/
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房屋出租");
}
}
另一个抽象角色UserService代码:
package cn.myspring.service;
/**
* 抽象角色
*/
public interface UserService {
public void add() ;
public void update() ;
public void delete() ;
public void search() ;
}
真实角色UserServiceImpl代码:
package cn.myspring.service;
/**
* 真实角色
*/
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("增加用户");
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void search() {
System.out.println("查询用户");
}
}
客户端角色Client代码:
package cn.my.dynamicproxy;
import cn.myspring.service.UserService;
import cn.myspring.service.UserServiceImpl;
/**
* 租客
*/
public class Client {
public static void main(String[] args) {
//动态代理类
ProxyInocationHandler pih = new ProxyInocationHandler() ;
//真实角色类
Host host = new Host() ;
pih.setTarget(host) ;
//Rent的代理对象
Rent proxy = (Rent) pih.getProxy() ;
proxy.rent() ;
//真实角色类
UserService userService = new UserServiceImpl() ;
pih.setTarget(userService) ;
//UserService的代理对象
UserService uproxy = (UserService) pih.getProxy() ;
System.out.println("---------------------------");
uproxy.add() ;
System.out.println("---------------------------");
uproxy.update();
System.out.println("---------------------------");
uproxy.delete() ;
System.out.println("---------------------------");
uproxy.search() ;
}
}
运行Client代码,控制台打印信息如下:
态代理是代理接口的,只要有接口就能代理
比如下面:
其中这个打印信息 : 执行 。。。方法 , 是动态代理类ProxyInocationHandler中的log日志方法打印的