代理模式到aop的学习
例一:
直接采用一个日常租房的例子来理解
首先 租房这个行为是租客、中介、房东都会去执行的行为,但是房东租房由中介去代理完成
定义Renting接口
public interface Renting {
//租房
void rent();
}
房东Landlord实现接口
public class Landlord implements Renting{
@Override
public void rent() {
System.out.println("劳资要租房!!");
}
}
中介Agent实现接口
中介除了会代理租房外,还会帮助办理一些其他的事务
这里我们使用组合来获取房东的属性
public class Agent implements Renting{
//组合
private Landlord landlord;
public void setLandlord(Landlord landlord) {
this.landlord = landlord;
}
//代理租房
@Override
public void rent() {
contract();
landlord.rent();
}
//会帮助房东办理相关手续
public void contract(){
System.out.println("中介帮你办你签合同");
}
}
服务类Client 完成租房
public class Client {
public static void main(String[] args) {
//房东
Landlord landlord = new Landlord();
Agent agent = new Agent();
//注入相关属性
agent.setLandlord(landlord);
agent.rent();
}
}
结果示例
中介帮你办你签合同
劳资要租房!!
例二:
采用一个对用户的CRUD的例子来理解
定义接口
public interface UserService {
void add();
void delete();
void update();
void query();
}
实现接口
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加了一个User!");
}
@Override
public void delete() {
System.out.println("删除了一个User!");
}
@Override
public void update() {
System.out.println("更新了一个User!");
}
@Override
public void query() {
System.out.println("查询了一个User!");
}
}
创建代理类
此代理类首先代理实现了CRUD功能
此外,如果我还需要对原有的操作进行功能的扩展,可以不对其原来的代码进行修改,直接新增,这就是代理模式的好处
public class UserServiceProxy implements UserService{
//组合获取相关属性
UserServiceImpl userService;
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
//好处是不用去修改原来的业务代码
@Override
public void add() {
printDebug("add");
userService.add();
}
@Override
public void delete() {
printDebug("delete");
userService.delete();
}
@Override
public void update() {
printDebug("update");
userService.update();
}
@Override
public void query() {
printDebug("query");
userService.query();
}
//新增的功能
public void printDebug(String method){
System.out.println("[DEBUG] 调用了"+method+"方法");
}
}
服务类Client 完成相关操作
public class Client {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
UserServiceProxy userServiceProxy = new UserServiceProxy();
userServiceProxy.setUserService(userService);
userServiceProxy.add();
}
}
结果示例
[DEBUG] 调用了add方法
增加了一个User!
静态代理和动态代理的区别
静态代理:由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
动态代理:动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
仍采用上面那个例子
UserService与UserServiceImpl与上同
创建ProxyInvocationHandler 实现 InvocationHandler接口
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);
}
//重写invoke方法 处理代理实例 并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
printDebug(method.getName());
Object result = method.invoke(target,args);
return result;
}
public void printDebug(String method){
System.out.println("[DEBUG] 调用了"+method+"方法");
}
}
//可以复用此模板
实现类
public class Client {
public static void main(String[] args) {
//真实角色
UserServiceImpl userService = new UserServiceImpl();
//代理角色 不存在
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//设置要代理的对象
pih.setTarget(userService);
//动态生成代理类
UserService proxy = (UserService) pih.getProxy();
proxy.add();
}
}
结果示例
[DEBUG] 调用了add方法
增加了一个User!