SpringAOP的底层实现就是代理模式,那么代理模式是什么呢?
代理分为静态代理和动态代理
它们的区别其实就是灵活性,静态代理一般都是写死的代码,而动态代理则是自动生成的,相对来说比较灵活
代理的角色:
-
抽象角色(如:卖房):一般使用接口或抽象类
-
真实角色(如:房东):被代理的角色
-
代理角色(如:房产中介):代理真实角色,代理真实角色后,一般会添加额外操作
-
访问代理的角色(如:我)
1、静态代理
情景:我要买房,我找到房产中介,房产中介拿房东的房给我看
抽象角色接口:卖房
/**
* 卖房
*/
public interface Sellers {
public void sell();
}
真实角色:房东
/**
* 房东
*/
public class Landlord implements Sellers {
@Override
public void sell() {
System.out.println("房东要出租房子");
}
}
代理角色:房产中介
/**
* 房产中介
*/
public class Intermediary implements Sellers {
private Landlord landlord;
public Intermediary(Landlord landlord) {
this.landlord= landlord;
}
@Override
public void sell() {
host.sell();
}
public void showings(){
System.out.println("中介带你看房");
}
}
访问代理的角色:我
/**
* 我
*/
public class Me{
public static void main(String[] args) {
Intermediary intermediary = new Intermediary(new Landlord());
intermediary.sell();
intermediary.showings();
}
}
2、动态代理
情景:与静态代理相同
情景:我要买房,我找到房产中介,房产中介拿房东的房给我看
抽象角色接口:卖房
/**
* 卖房
*/
public interface Sellers {
public void sell();
}
真实角色:房东
/**
* 房东
*/
public class Landlord implements Sellers {
@Override
public void sell() {
System.out.println("房东要出租房子");
}
}
代理角色:房产中介
package com.hu.demo04;
import com.hu.demo03.Rent;
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;
}
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 {
Object result = method.invoke(target, args);
showings();
return result;
}
public void showings(){
System.out.println("中介带你看房");
}
}
访问代理的角色:我
package com.hu.demo03;
public class Me {
public static void main(String[] args) {
Landlord landlord = new Landlord(); //真实角色
ProxyInvocationHandler pih = new ProxyInvocationHandler(); //代理角色
pih.setTarget(landlord); //通过调用程序处理角色来处理我们要调用的接口对象
Sellers proxy = (Sellers)pih.getProxy(); //获得动态代理对象
proxy.sell(); //执行代理接口的方法
}
}
动态代理的好处
-
可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
-
公共业务交给代理角色,实现了业务的分工
-
公共业务发生扩展时,方便集中管理
-
一个动态代理类代理的是一个接口,一般对应的一类业务
-
一个动态代理类可以代理多个类,只要是实现了同一个接口即可