学习AOP之前,你必须要了解动态代理。
静态代理
角色分析:
- 抽象角色:一般会使用接口或者抽象类
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
- 客户:访问代理对象的人
代码分析
- 抽象角色
public interface Rent {
void rent();
}
- 真实角色
public class Landlord implements Rent {
@Override
public void rent() {
System.out.println("出租房子");
}
}
- 代理角色
public class ProxyRent implements Rent {
//被代理的类
private Landlord landlord; //传入被代理的类
public ProxyRent(Landlord landlord){
this.landlord = landlord;
}
@Override
public void rent() {
SeeHouse();
landlord.rent();
contract();
agencyFee();
}
public void SeeHouse(){
System.out.println("房屋中介看您看房");
}
public void contract(){
System.out.println("房屋中介安排您们签合同");
}
public void agencyFee(){
System.out.println("房屋中介收取中介费");
}
}
- 客户
public class Test {
public static void main(String[] args) {
ProxyRent proxyRent = new ProxyRent(new Landlord());
proxyRent.rent();
}
}
- 结果
如果您还是不明白,那我再举一个栗子。
- 抽象角色:Service 接口
public interface Service {
void add();
void sub();
void mul();
void div();
}
- 真实角色:被代理的角色(实现了Service 接口)
public class ServiceImpl implements Service {
@Override
public void add() {
System.out.println("加法");
}
@Override
public void sub() {
System.out.println("减法");
}
@Override
public void mul() {
System.out.println("乘法");
}
@Override
public void div() {
System.out.println("除法");
}
}
- 代理角色:(实现了Service 接口并传入ServiceImpl 对象,且有额外操作log() )
public class Log implements Service{
private ServiceImpl serviceImpl;
public Log(ServiceImpl serviceImpl){
this.serviceImpl = serviceImpl;
}
@Override
public void add() {
log();
serviceImpl.add();
}
@Override
public void sub() {
log();
serviceImpl.sub();
}
@Override
public void mul() {
log();
serviceImpl.mul();
}
@Override
public void div() {
log();
serviceImpl.div();
}
public void log(){
System.out.println("我是添加的日志");
}
}
- 客户:访问代理对象的人
public class Test {
public static void main(String[] args) {
Log log = new Log(new ServiceImpl());
log.add();
log.sub();
log.mul();
log.div();
}
}
静态代理,到此结束。
动态代理(Proxy与InvocationHandler)
- 抽象角色:一般会使用接口或者抽象类
public interface Rent {
void rent();
}
- 真实角色:被代理的角色
public class Landlord implements Rent {
@Override
public void rent() {
System.out.println("出租房子");
}
}
- 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
//通过这个类,获取代理类
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Rent rent;
public void setRent(Rent rent){
this.rent = rent;
}
/*
返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
loader:定义代理类的类加载器
interfaces:代理类要实现的接口列表
h:指定调用处理程序(InvocationHandler)
*/
public Rent getProxyInstance(){
return (Rent)Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(), this);
}
@Override
//处理代理实例上的方法调用并返回结果。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
Object result = method.invoke(rent, args); // 反射
return result;
}
public void seeHouse(){
System.out.println("房屋中介带你看房");
}
}
- 客户:访问代理对象的人
public class Test {
public static void main(String[] args) {
//真实对象
Landlord landlord = new Landlord();
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setObject(landlord);
//获取代理对象
Rent instance = (Rent)pih.getProxyInstance();
instance.rent();
}
}
如果你看不懂,没关系,我给你提供了获取万能代理类
//通过这个类,获取代理类
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
public void setObject(Object target){
this.target = target;
}
/*
返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
loader:定义代理类的类加载器
interfaces:代理类要实现的接口列表
h:指定调用处理程序(InvocationHandler)
*/
public Object getProxyInstance(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(), this);
}
@Override
//处理代理实例上的方法调用并返回结果。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
Object result = method.invoke(target, args); // 反射
return result;
}
public void seeHouse(){
System.out.println("房屋中介带你看房");
}
}
下一篇:AOP