1、静态代理
1、角色分析:
- 抽象角色:共同完成的一件事情,一般会使用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作。
- 客户:访问代理对象的人!
2、代码步骤:
//结婚
interface Marry{
void HappyMarry();
}
2. ```java
// 你去结婚
class You implements Marry{
@Override
public void HappyMarry() {
System.out.println("我要结婚了");
}
}
// 代理对象,帮助你结婚
class WeddingCompany implements Marry{
private Marry target;
public WeddingCompany(Marry target) {
this.target = target;
}
@Override
public void HappyMarry() {
before(); // 帮你布置现场
this.target.HappyMarry(); // 你去结婚
after(); // 收尾款
}
private void before() {
System.out.println("布置现场");
}
private void after() {
System.out.println("收尾款");
}
}
4. ```java
public class StaticProxy {
public static void main(String[] args) {
// 代理对象帮你布置现场 收尾款
WeddingCompany weddingCompany = new WeddingCompany(new You());
weddingCompany.HappyMarry();// 你只需要自己结婚即可
}
}
3、静态代理的好处:
- 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
- 公共也就交给代理角色!实现了业务的分工!
- 公共业务发生扩展的时候,方便集中管理!
4、缺点:
- 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低
2、动态代理
1、JDK 动态代理
1、使用 JDK 动态代理,使用 Proxy
类里面的方法创建代理对象
Proxy
提供用于创建动态代理类和实例的静态方法
调用 newProxyInstance 方法
方法中有三个参数:
-
第一个参数:类加载器
-
第二个参数:增强方法所在的类,这个类实现的接口,支持多个接口
-
第三个参数:实现这个接口 InvocationHandler,创建代理对象,写增强的方法
2、步骤
1、创建接口,定义方法
public interface UserDao {
int add(int a,int b);
String update(String id);
}
2、创建接口实现类,实现方法
public class UserDaoImpl implements UserDao {
@Override
public int add(int a, int b) {
System.out.println("add方法执行了。。。。");
return a+b;
}
@Override
public String update(String id) {
System.out.println("update方法执行了。。。。");
return id;
}
}
3、使用 Proxy 类创建接口代理对象
package com.yb.spring5;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class JDKProxy {
public static void main(String[] args) {
//创建接口实现类代理对象
Class[] interfaces = {UserDao.class};
/* Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() {
@Override //匿名内部类,或者创建一个类,然后这里写上类对象
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
});*/
UserDaoImpl userDao = new UserDaoImpl();
//获取代理对象
UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
//调用对应的方法
int res = dao.add(1, 2);
System.out.println("结果:"+res);
}
}
//创建代理对象代码
class UserDaoProxy implements InvocationHandler{
//1、创建的是谁的代理对象,把谁传递过来
private Object obj;
//有参数构造传递
public UserDaoProxy(Object obj){
this.obj = obj;
}
//增强的逻辑
//参数 proxy:代理对象
//参数 method:当前的方法
//参数 args:参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法之前
System.out.println("方法之前执行..."+method.getName()+"方法:传递的参数"+ Arrays.toString(args));
//被增强的方法执行
Object res = method.invoke(obj, args);
//方法之后
System.out.println("方法之后执行..."+obj);
return res;
}
}
//结果
方法之前执行...add方法:传递的参数[1, 2]
add方法执行了。。。。
方法之后执行...com.yb.spring5.UserDaoImpl@355da254
结果:3
动态代理的好处:
- 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
- 公共也就交给代理角色!实现了业务的分工!
- 公共业务发生扩展的时候,方便集中管理!
- 一个动态代理类代理的是一个接口,一般就是对应的一类业务
方法:传递的参数[1, 2]
add方法执行了。。。。
方法之后执行…com.yb.spring5.UserDaoImpl@355da254
结果:3
动态代理的好处:
* 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
* 公共也就交给代理角色!实现了业务的分工!
* 公共业务发生扩展的时候,方便集中管理!
* 一个动态代理类代理的是一个接口,一般就是对应的一类业务
* 一个动态代理类可以代理多个类,只要是实现了同一个接口即可!