为什么学代理?因为这就是springAOP的底层(springAOP和springMVC)
1、静态代理(方便横向开发)
角色分析:
抽象角色:一般会使用接口 或者抽象类来解决
真实角色:被代理的角色
代理角色:代理真实角色 代理真实角色后 我们会进行一系列操作
客户:访问代理对象的人
一个简单的静态代理demo:
该demo的真实角色:Host类 实现rent接口
package com.proxytest.demo2;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
*
* @author Sw_Ljb
* @version 1.0
* @ClassName Host
* @Date 2022/4/20下午6:39
*/
public class Host implements rent {
@Override
public void rent() {
System.out.println("我要租房子");
}
}
抽象角色:rent接口
package com.proxytest.demo2;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
*
* @author Sw_Ljb
* @version 1.0
* @ClassName rent
* @Date 2022/4/20下午6:38
*/
public interface rent {
void rent();
}
代理角色:proxyhome类实现rent接口
package com.proxytest.demo2;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
*
* @author Sw_Ljb
* @version 1.0
* @ClassName ProxyHome
* @Date 2022/4/20下午6:42
*/
public class ProxyHome implements rent{
//代理的人
private Host host;
public ProxyHome() {
}
//设置代理的对象
public void setHost(Host host) {
this.host = host;
}
public void seeHome(){
System.out.println("中介带你看房");
}
public void SignTheContract(){
System.out.println("中介签合同");
}
@Override
public void rent() {
seeHome();
SignTheContract();
host.rent();
}
}
客户:customers
package com.proxytest.demo2;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
*
* @author Sw_Ljb
* @version 1.0
* @ClassName Customers
* @Date 2022/4/20下午6:39
*/
public class Customers {
public static void main(String[] args) {
//方式二 找不到房主了 要找代理 房东了
//还是要用房东 但是 租房的找不到房东 房东只想拿钱 不想搞其他的 这就要招代理
Host host = new Host();
ProxyHome proxyHome = new ProxyHome();
proxyHome.setHost(host);
proxyHome.rent();
}
}
代理模式好处:
真实角色的操作更加纯粹 不用关注一些公共的业务
公共的就交给代理角色 实现业务的分工
公共业务发生扩展的时候 方便集中管理
2、动态代理(底层 反射(动态性))
动态代理 和静态代理角色一样
动态代理的类是动态生成的 不是我们直接写好的
动态代理分为两大类:基于接口的动态代理 基于类的动态代理
基于接口实现:==JDK的动态代理【我们在这里使用】
基于类的实现:==cglib类
java字节码的实现:javasist
需要了解两个类:proxy(代理):生成实例 invocationhandler(调用处理程序):返回结果 关联他
一个简单的动态代理模式demo:
//抽象接口
package com.proxytestPro.demo01;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
*
* @author Sw_Ljb
* @version 1.0
* @ClassName rent
* @Date 2022/4/20下午6:38
*/
public interface rent {
void rent();
}
//真实对象
package com.proxytestPro.demo01;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
*
* @author Sw_Ljb
* @version 1.0
* @ClassName Host
* @Date 2022/4/20下午6:39
*/
public class Host implements rent {
@Override
public void rent() {
System.out.println("我要租房子");
}
}
//动态代理
package com.proxytestPro.demo01;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
*
* @author Sw_Ljb
* @version 1.0
* @ClassName proxyInvocationtest
* @Date 2022/4/20下午7:45
*/
public class proxyInvocationtest implements InvocationHandler {
//被代理的接口
private Object obj;
/*
Foo f = (Foo) Proxy.newProxyInstance(
Foo.class.getClassLoader(), (代理类的一个接口)new Class<?>[] { Foo.class }, handler);\
*/
public void setObj(Object obj) {
this.obj = obj;
}
//生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
//调用处理代理实例 并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质 就是反射机制实现
Object result = method.invoke(obj, args);
return result;
}
}
//客户
package com.proxytestPro.demo01;
import com.proxytest.demo03.UserService;
import com.proxytest.demo03.UserServiceImpl;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
*
* @author Sw_Ljb
* @version 1.0
* @ClassName client
* @Date 2022/4/20下午7:53
*/
public class client {
public static void main(String[] args) {
//真实角色 ==》房东
Host host = new Host();
UserServiceImpl usi = new UserServiceImpl();
//代理类 现在没有 要自己生成
//设置代理对象 代理的啥
proxyInvocationtest pis = new proxyInvocationtest();
pis.setObj(usi);
//生成代理对象
// rent proxy = (rent) pis.getProxy();
//
// proxy.rent();
UserService proxy1 = (UserService) pis.getProxy();
proxy1.query();
}
}
代理步骤:
1、接口
2、真实角色
3、代理角色
4、客户端访问代理角色
缺点:一个真实角色 就会产生一个代理角色 开发效率变低