代理模式分为静态代理和动态代理
类似于生活中的中介代理房东租房、婚介代理要结婚的情侣布置婚礼现场等等。
拿房东租房为例
package com.curtian.study.static_proxy.demo1;
public interface Rent {
void rent();
}
package com.curtian.study.static_proxy.demo1;
/**
* 房东
*/
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东租房子");
}
}
package com.curtian.study.static_proxy.demo1;
public class Proxy implements Rent{
private Host host;
@Override
public void rent() {
seeHouse();
host.rent();
hetong();
rate();
}
public Proxy(Host host) {
this.host = host;
}
private void seeHouse(){
System.out.println("中介带看房子");
}
private void hetong(){
System.out.println("签署租赁合同");
}
private void rate(){
System.out.println("收取中介费");
}
}
从代码中我们也可以发现,中介只是在被代理的类的方法上加了一些额外的方法(seeHouse、hetong、rate)
由接口(Rent租房接口)
、真实角色(Host房东)
、代理角色(Proxy房屋中介)
组成。
是可以是使真实角色操作更加存粹(房东只管租房一件事情),很明显的体现了面向对象七大原则的单一职责原则。公共业务就交给代理角色。
一个真实角色就对应一个代理角色,比如房东对应房屋中介、要结婚的情侣对应婚介所
拥有静态代理的所有优点以及可以动态生成代理类。
动态代理分为三大类:
(目前博主只了解了jdk动态代理)
Proxy类
和InvocationHandler接口
Proxy用于生成代理类,实现InvocationHandler接口可以通过反射获取被代理的类的方法, 然后在此基础上添加一些附属操作
给所有类的方法加一些日志。
package com.curtian.study.static_proxy.demo2;
public interface Userservice {
void add();
void delete();
}
package com.curtian.study.static_proxy.demo2;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements Userservice{
@Override
public void add() {
System.out.println("加法");
}
@Override
public void delete() {
System.out.println("减法");
}
}
package com.curtian.study.dynamic_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的对象
private Object target;
public void setTarget(Object target){
this.target = target;
}
/**
* 生成代理类
* @return
*/
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* 当代理类执行方法的时候,会回调到这个方法,附属操作也是在这里加的
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(proxy.getClass().getName());
log("调用了" + method.getName() + "方法");
return method.invoke(target, args);
}
private void log(String msg){
System.out.println(msg);
}
}
/**
* 动态代理
* 介绍:动态代理和静态代理角色一样
* 动态代理的代理类是动态生成的,不是我们直接写好的!
* 动态代理分为两大类:基于接口的动态代理,基于类的动态代理。
* 1.基于接口--Jdk动态代理【本次示例】
* 2.基于类:cglib
* 3.java字节码实现: javasist
* 示例中的两个核心类/接口,Proxy类、invocationHandler接口
*
* */
public class Main {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
proxyInvocationHandler.setTarget(userService);
Userservice proxy = (Userservice) proxyInvocationHandler.getProxy();
proxy.add();
proxy.delete();
}
}
运行情况: