目录
代理模式为某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。这样做的好处:扩展目标对象的功能,核心功能是方法增强。代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。简单的说就是,我们在访问实际对象时,是通过代理对象来访问的,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。
代理有不同的形式:静态代理和动态代理。其中动态代理包括 JDK代理和cglib代理。
实现静态代理的步骤:
代理类跟目标类需要实现同一个接口的方法,
在代理类中定义目标的对象,编写代理方法,在代理方法中使用目标对象的方法及一些扩展操作。
创建代理类对象和目标对象,将目标对象传给代理类对象,代理类对象使用代理方法。
代码实现:
1、首先,我们创建一个Siner接口。这个接口就是歌星(被代理类),和经纪人(代理类)的公共接口,他们都有上唱歌的行为。这样,歌星唱歌就可以让经纪人来代理执行,经纪人可以在歌星唱歌前、后进行增强。
- public interface Singer {
-
- /**
- * 歌星都能唱歌
- */
- void sing();
- }
2、创建被代理对象实现接口,完成具体的业务逻辑
MaleSinger 类实现Singer接口。MaleSinger 可以具体实唱歌的动作:
- /**
- * 男歌星
- */
- public class MaleSinger implements Singer{
-
- private String name;
-
- public MaleSinger(String name) {
- this.name = name;
- }
-
- /**
- * 歌星都能唱歌
- */
- public void sing() {
- System.out.println(name+"开始唱歌了……");
- }
- }
3、 创建代理类实现接口,完成委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。
- /**
- * 经纪人
- */
- public class Agent implements Singer{
-
- private Singer singer;
-
- public Agent(Singer singer) {
- this.singer = singer;
- }
-
- /**
- * 歌星都能唱歌
- */
- public void sing() {
- System.out.println("节目组找过来!需要演出,谈好演出费用。。。。。");
- singer.sing();
- System.out.println("结算费用,下一次合作预约。。。。。。");
- }
- }
4、客户端使用操作与分析
- public class StaticProxyTest {
- public static void main(String[] args) {
-
- //被代理的歌星周杰伦,他的唱歌由代理对象agent(经纪人)完成
- Singer singer=new MaleSinger("周杰伦");
- //生成代理对象,并将周杰伦传给代理对象
- Agent agent=new Agent(singer);
- //由代理对象经纪人代理唱歌
- agent.sing();
- }
- }

缺点:代理对象需要和目标对象实现一样的接口,所以会产生很多的代理类。一旦增加方法,目标类和代理类都要进行维护。
在java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过这个类和这个接口可以生成JDK动态代理类和动态代理对象。JDK动态代理的前提是必须有接口,JDK 动态代理会为每个业务接口动态生成相应的代理类实现,并加载到 JVM 中,然后创建对应的代理实例对象。
JDK 动态代理的实现原理:动态创建代理类,然后通过指定类加载器进行加载。
代码实现:
接口:
UserService
- /**
- * @author :Rk.
- * @date : 2022/9/10
- */
- public interface UserService {
-
- String findAllUsers();
-
- }
接口实现类:
- /**
- * @author :Rk.
- * @date : 2022/9/10
- */
- public class UserServiceImpl implements UserService {
- @Override
- public String findAllUsers() {
- System.out.println("查询所有用户");
- return "查询到用户:12345";
- }
- }
使用jdk动态代理实现代理类:
- /**
- * @author :Rk.
- * @date : 2022/9/10
- */
- public class UserTest {
- public static void main(String[] args) {
- UserServiceImpl userServiceimpl=new UserServiceImpl();
- UserService userService = (UserService)Proxy.newProxyInstance(UserTest.class.getClassLoader(), new Class[]{UserService.class}, new InvocationHandler() {
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- //前置增强
- System.out.println("在查询前进行增强!");
- //调用userservice中的findall方法
- Object invoke = method.invoke(userServiceimpl, args);
- //后置增强
- System.out.println("在查询后进行增强!");
- //方法返回值
- return invoke+"返回值";
- }
- });
-
- String allUsers = userService.findAllUsers();
- System.out.println(allUsers);
- }
- }
