【玩转23种Java设计模式】结构型模式篇,java从入门到精通第五版

本文深入解析了Spring MyBatis的动态代理实现,展示了如何通过MapperFactoryBean创建DAO层接口的代理实例,并在其中处理SQL逻辑。同时,详细介绍了Bean定义的注册过程,以及在测试中如何从Spring容器获取并使用这个代理bean。

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.METHOD})

public @interface Select {

String value() default “”;

}

2、Dao层接口(IUserDao)

public interface IUserDao {

@Select(“select * from user where id = #{id}”)

String selectById(Integer id);

}

3、代理类(MapperFactoryBean)

@Slf4j

public class MapperFactoryBean implements FactoryBean {

private Class mapperInterface;

public MapperFactoryBean(Class mapperInterface) {

this.mapperInterface = mapperInterface;

}

@Override

public T getObject() throws Exception {

InvocationHandler handler = (proxy, method, args) -> {

Select select = method.getAnnotation(Select.class);

log.info(“query sql:{}”, select.value());

log.info(“param:{}”, args[0]);

return “1, 张三(模拟从数据库查询的返回)”;

};

return (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{mapperInterface}, handler);

}

@Override

public Class<?> getObjectType() {

return mapperInterface;

}

@Override

public boolean isSingleton() {

return true;

}

}

MapperFactoryBean 通过继承 FactoryBean ,提供bean对象,也就是方法T getObject() 。在方法 getObject()

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

中提供类的代理以及模拟对sql语句的处理,这里包含了用户调用dao层方法时候的处理逻辑。

4、Bean定义注册到Spring容器(RegisterBeanFactory)

public class RegisterBeanFactory implements BeanDefinitionRegistryPostProcessor {

@Override

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

GenericBeanDefinition beanDefinition = new GenericBeanDefinition();

beanDefinition.setBeanClass(MapperFactoryBean.class);

beanDefinition.setScope(“singleton”);

beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(IUserDao.class);

BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDefinition, “userDao”);

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);

}

@Override

public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

}

}

我们将代理的bean交给spring容器管理,以方便我们获取到代理的bean。这里是在spring中关于⼀个bean注册过程的源码。GenericBeanDefinition ,用于定义⼀个bean的基本信息,也包括可以透传给构造函数信息,最后使用BeanDefinitionReaderUtils.registerBeanDefinition,进行bean的注册,也就是注册到DefaultListableBeanFactory 中。

5、spring-mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns=“http://www.springframework.org/schema/beans”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd">

6、测试

@SpringBootTest

public class ApplicationTests {

@Test

public void test() {

BeanFactory beanFactory = new ClassPathXmlApplicationContext(“spring-mybatis.xml”);

IUserDao userDao = beanFactory.getBean(“userDao”, IUserDao.class);

String res = userDao.selectById(1);

System.out.println("res = " + res);

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值