代理模式
代理的好处
可以使真实角色更加纯粹,不用去关注一些公共的业务
公共的业务交给代理角色,实现了业务的分工
公共业务发生扩展时,方便集中管理
代理模式的分类
静态代理
静态代理的实现步骤
- 抽象具体业务
- 真实角色实现或继承抽象接口
- 代理角色实现或继承抽象接口
- 客户端访问代理类
静态代理的缺点
一个真实角色会产生一个真实代理,代码量会翻倍,开发效率变低
案例 1
1:
public interface RentDao {
void rent();
}
2:
public class Host implements RentDao{
@Override
public void rent() {
System.out.println("房东出租房子!");
}
}
3:
public class AgentProxy implements RentDao{
private Host host;
public void setAgentProxy(Host host){
this.host = host;
}
@Override
public void rent() {
this.lookHose();
host.rent();
this.hetong();
}
private void lookHose(){
System.out.println("中介带领看房子");
}
private void hetong(){
System.out.println("中介带领签合同");
}
}
4:
public class User {
public static void main(String[] args) {
Host host = new Host();
AgentProxy agent = new AgentProxy();
agent.setAgentProxy(host);
agent.rent();
}
}
案例 1 - 记录日志功能
public interface UserService {
void add();
void delete();
void update();
void query();
}
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("add...");
}
@Override
public void delete() {
System.out.println("delete...");
}
@Override
public void update() {
System.out.println("update...");
}
@Override
public void query() {
System.out.println("query...");
}
}
public class HandlerProxy implements UserService{
private UserService userService;
public void setUserService(UserService userService){
this.userService = userService;
}
@Override
public void add() {
this.log("add");
userService.add();
}
@Override
public void delete() {
this.log("delete");
userService.delete();
}
@Override
public void update() {
this.log("update");
userService.update();
}
@Override
public void query() {
this.log("query");
userService.query();
}
void log(String action){
System.out.println("进行了" + action + "操作");
};
}
public class Test {
public static void main(String[] args) {
HandlerProxy handlerProxy = new HandlerProxy();
UserService userService = new UserServiceImpl();
handlerProxy.setUserService(userService);
handlerProxy.add();
}
}
#
进行了add操作
add...
动态代理
为了解决静态代理的缺点,应使用动态代理。可以代理多个类。
动态代理的和静态代理所代理的角色一样。
动态代理的代理类是动态生成的,本质是反射实现的。
动态代理方式
- 基于接口的动态代理 - JDK 的动态代理
- 基于类的动态代理 - cglib
- Java字节码 - Javassit
动态代理的两个重要的类
java.util.reflect 包下:
1. Proxy - 生成代理类
2. InvocationHandler 接口,反射包 - 调用处理程序,处理代理实例并返回一个结果
动态代理实现
public interface UserService {
void add();
void delete();
void update();
void query();
}
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("add...");
}
@Override
public void delete() {
System.out.println("delete...");
}
@Override
public void update() {
System.out.println("update...");
}
@Override
public void query() {
System.out.println("query...");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvicationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target){
this.target = target;
}
public Object getProxy(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
this.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target);
return result;
}
void log(String action){
System.out.println("执行了" + action + "方法");
}
}
public class Test {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
ProxyInvicationHandler pih = new ProxyInvicationHandler();
pih.setTarget(userService);
UserService proxy = (UserService) pih.getProxy();
proxy.add();
}
}