栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式 代理模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式 代理模式

文章目录

代理模式情景代理模式实战

代理模式情景

代理模式用于某些资源的访问, 对象的类 易用操作上提供方便使用的代理服务. 用到的一些组件会提供给你简单易用的方式控制原本需要编写很多代码进行使用的服务类.
例如rpc框架, 在拿到jar包对接口的描述后, 会生成代理类, 当调用接口的时候, 通过代理类发出socket信息进行通信.
mybatis框架, 只写了接口, 框架会在底层生成代理类去执行crud操作.

代理模式实战

模拟mybatis 生成代理类.
类图如下

编写自定义注解Select

@documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Select {

    String value() default "";
}

定义dao接口

public interface IUserDao {

    @Select("select userName from user where id = #{uId}")
    String queryUserInfo(String uId);
}

代理类定义MapperFactoryBean
通过继承FactoryBean,提供bean对象,也就是方法;T getObject()。
getObject 中进行反射操作.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.FactoryBean;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;


// 通过继承FactoryBean,提供bean对象,也就是方法;T getObject()。
public class MapperFactoryBean implements FactoryBean {

    private Logger logger = LoggerFactory.getLogger(MapperFactoryBean.class);

    private Class mapperInterface;

    // 提供构造函数来透传需要被代理类,Class mapperInterface,在mybatis中也是使用这样的方式进行透传。
    public MapperFactoryBean(Class mapperInterface) {
        this.mapperInterface = mapperInterface;
    }

    //在方法 getObject()中提供类的代理以及模拟对sql语句的处理,这里包含了用户调用dao层方法时候的处理逻辑。
    @Override
    public T getObject() {
        // 通过代理, 把参数进行赋值.
        InvocationHandler handler = ((proxy, method, args) -> {
            Select select = method.getAnnotation(Select.class);
            logger.info("sql : {}", select.value().replace("#{uId}", args[0].toString()));
            logger.info("args[0] : {}",   args[0].toString());
            //  此处return的是接口返回的结果, 实际中为数据库查询的结果, 此处写死一个.
            return "张三";
        });
        return (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{mapperInterface}, handler);
    }

    // getObjectType()提供对象类型反馈,以及isSingleton()返回类是单例的。
    @Override
    public Class getObjectType() {
        return mapperInterface;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

将Bean定义注册到Spring容器

import com.thc.design.IUserDao;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;


public class RegisterBeanFactory implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // 用于定义一个bean的基本信息setBeanClass(MapperFactoryBean.class);,
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();

        // 将代理的bean交给spring容器管理
        beanDefinition.setBeanClass(MapperFactoryBean.class);
        beanDefinition.setScope("singleton");
        //可以透传给构造函数信息addGenericArgumentValue(IUserDao.class);
        beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(IUserDao.class);

        //BeanDefinitionReaderUtils.registerBeanDefinition,进行bean的注册,也就是注册到DefaultListableBeanFactory
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDefinition, "userDao");
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}

定义spring-config.xml




    


测试类

public class ApiTest {

    private Logger logger = LoggerFactory.getLogger(ApiTest.class);

    @Test
    public void test_IUserDao() {
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config.xml");
        IUserDao userDao = beanFactory.getBean("userDao", IUserDao.class);
        String res = userDao.queryUserInfo("100001");
        logger.info("测试结果: {}", res);
    }
}

运行测试类 , 结果如下

15:40:51.556 [main] INFO  c.thc.design.agent.MapperFactoryBean - sql : select userName from user where id = 100001
15:40:51.556 [main] INFO  c.thc.design.agent.MapperFactoryBean - args[0] : 100001
15:40:51.556 [main] INFO  com.thc.design.ApiTest - 测试结果: 张三
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/782237.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号