一、代理
- 代理有三种模式
- 在静态代理模式之下,我们显示地创建代理类,代理类持有被代理类的对象,实现与被代理类的相同接口,并且
增添相应的业务逻辑
,以达到代理的效果。
1、静态代理
代码步骤:
1.接口
2.真实角色
3.代理角色
4.客户端访问代理角色
- 假设:房东要出租,但是不想要麻烦自己,然后就是装让给中介,就现在,房东是出租房,中介也是出租房,但是中介是管理房东房
/**
* @Author Lin_Home
* @Date 2020/8/18 14:51
* @Version 1.0
*/
/**
* 静态代理的使用
* */
//定义一个服务的类
interface Server{
//定义一个客户询问话题
void say(String name);
}
//定义一个人工服务对接的实现类
class Waiter implements Server{
@Override
public void say(String name) {
System.out.println(name+"你好,有什么问题需要为你服务");
}
}
//设置一个代理,目的就是解决一些琐碎的事情
class Proxy implements Server{
private Waiter waiter;
public Proxy(Waiter waiter) {
this.waiter = waiter;
}
@Override
public void say(String name) {
System.out.println("欢迎咨询10086"+name);
waiter.say(name);
System.out.println("谢谢"+name);
}
}
public class MainTest {
public static void main(String[] args) {
Waiter waiter = new Waiter();
Proxy boyPeople = new Proxy(waiter);
boyPeople.say("小米");
}
}
2、动态代理
-
创建一个处理类
-
必须要实现InvocationHandler 跟 调用Porty 方法
-
重写invoke(Object proxy, Method method, Object[] args)
- 参数一:proxy:代理类的对象
- 参数二:method:代理类对象调用的方法
- 参数三:args:代理类方法的参数
- 此方法就是编写代理的逻辑代码增强
-
- 定义一个接口
package porxy.com.cn;
/**
* @Author Lin_Home
* @Date 2020/8/6 14:34
* @Version 1.0
*/
public interface Send {
void chuzu();
}
- 实现代理接口
package porxy.com.cn;
/**
* @Author Lin_Home
* @Date 2020/8/6 16:13
* @Version 1.0
*/
public class Person implements Send {
@Override
public void chuzu() {
System.out.println("出租");
}
}
- 编写一个代理实现代理接口
package porxy.com.cn;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author Lin_Home
* @Date 2020/8/6 14:29
* @Version 1.0
*/
//这个代理你可以想是中介。中介想干什么就干什么
public class JdkPorxy implements InvocationHandler {
//被代理的接口(用户出租)
public Person person;
public JdkPorxy() {
}
public void setPerson(Person person) {
this.person = person;
}
//看房
public void seeHouse(){
System.out.println("看房");
}
//收中介费
public void fare(){
System.out.println("签约");
}
public JdkPorxy(Person person) {
this.person = person;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
person.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
Object invoke = method.invoke(person, args);
fare();
return invoke;
}
}
- 编写一个测试类
package porxy.com.cn;
/**
* @Author Lin_Home
* @Date 2020/8/6 16:34
* @Version 1.0
*/
public class MainTest {
public static void main(String[] args) {
JdkPorxy jdkPorxy = new JdkPorxy();
Person person = new Person();
jdkPorxy.setPerson(person);
Send proxy = (Send) jdkPorxy.getProxy(); //动态生成对应的代理类
proxy.chuzu();
}
}
3、cglib的动态代理(针对于类)
-
需要导入cglib的所需要的的库使用
-
通过cglib的动态代理它能够针对实现没有接口的目标类,进行动态代理。
-
实现原理
-
cglib它会生成目标类的子类实现,因此目标类作为父类注入,并且调用父类的方法
-
实现过程
-
创建目标类,此目标类不需要实现任何的接口
-
创建方法的拦截器类
- 此类实现MethodInterceptor
- 重写intercept方法
-
-
-
写一个类
package porxy.com.cn;
/**
* @Author Lin_Home
* @Date 2020/11/6 16:13
* @Version 1.0
*/
public class Person2 {
public void chuzu() {
System.out.println("房屋出租");
}
}
- 实现cgLib的核心方法 MethodInterceptor
package porxy.com.cn;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @Author Lin_Home
* @Date 2020/8/6 17:12
* @Version 1.0
*/
public class CgLibProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
seeHouse();
Person2 person = new Person2();
method.invoke(person,objects);
fare();
return null;
}
//看房
public void seeHouse(){
System.out.println("带房客看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
}
}
- 写一个测试类
package porxy.com.cn;
import net.sf.cglib.proxy.Enhancer;
/**
* @Author Lin_Home
* @Date 2020/11/6 16:34
* @Version 1.0
*/
public class MainTest {
public static void main(String[] args) {
//创建处理类的对象
CgLibProxy interceptor = new CgLibProxy();
//创建Enhancer对象,目的是增强对象
Enhancer enhancer = new Enhancer();
//获取字节文件
enhancer.setSuperclass(Person2.class);
//回调函数
enhancer.setCallback(interceptor);
//生成代理类对象
Person2 proxyWaiter = (Person2) enhancer.create();
proxyWaiter.chuzu();
}
}