jdk动态代理:
package com.luban.源码调试.postprocessor;
import com.luban.源码调试.dao.UserMapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.FactoryBean;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class MyFactoryBean implements FactoryBean,InvocationHandler {
// 返回new出来的代理对象
@Override
public Object getObject() throws Exception {
Class[] clazzs = new Class[]{UserMapper.class};
Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(),clazzs,this);
return proxy;
}
@Override
public Class<?> getObjectType() {
return UserMapper.class;
}
// proxy是代理对象,生成的代理对象
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入mapperScanner方法");
// 拿到mapper的方法
Method method1 = proxy.getClass().getInterfaces()[0].getMethod(method.getName(),null);
Select select = method1.getDeclaredAnnotation(Select.class);
String sql = select.value()[0];
StringBuffer sb = new StringBuffer();
//声明Connection对象
Connection con;
//驱动程序名
String driver = "com.mysql.jdbc.Driver";
//URL指向要访问的数据库名mydata
String url = "jdbc:mysql://47.101.219.60:3306/cjftest";
//MySQL配置时的用户名
String user = "root";
//MySQL配置时的密码
String password = "123456";
//遍历查询结果集
try {
//加载驱动程序
Class.forName(driver);
//1.getConnection()方法,连接MySQL数据库!!
con = DriverManager.getConnection(url, user, password);
if (!con.isClosed())
System.out.println("Succeeded connecting to the Database!");
//2.创建statement类对象,用来执行SQL语句!!
Statement statement = con.createStatement();
//3.ResultSet类,用来存放获取的结果集!!
ResultSet rs = statement.executeQuery(sql);
while (rs.next()) {
//获取stuname这列数据
String id = "id:" + rs.getInt("id") + " ";
//获取stuid这列数据
String name = "name:" + rs.getString("name") + " ";
sb.append(id + name);
}
rs.close();
con.close();
} catch (ClassNotFoundException e) {
//数据库驱动类异常处理
System.out.println("Sorry,can`t find the Driver!");
e.printStackTrace();
} catch (SQLException e) {
//数据库连接失败异常处理
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
}
package com.luban.源码调试.postprocessor;
import com.luban.源码调试.dao.UserMapper;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar{
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 把class转成beandefinition
BeanDefinitionBuilder beanDefinitionBuilder =
BeanDefinitionBuilder.genericBeanDefinition(UserMapper.class);
GenericBeanDefinition beanDefinition = (GenericBeanDefinition) beanDefinitionBuilder.getBeanDefinition();
// 偷天换日,修改对应的class,这样搞出来的最终类就是代理对象了
beanDefinition.setBeanClass(MyFactoryBean.class);
registry.registerBeanDefinition("UserMapper",beanDefinition);
}
}
package com.luban.源码调试.dao;
import org.apache.ibatis.annotations.Select;
public interface UserMapper {
@Select({
"select * from cjfmybatistest "
})
public String getUser();
}
package com.luban.源码调试.config;
import com.luban.源码调试.postprocessor.MyImportBeanDefinitionRegister;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(value = {MyImportBeanDefinitionRegister.class})
//@ComponentScan("com.luban.源码调试")
public class AppConfig {
// @Bean
// public String abc(){
// return "abc";
// }
}
package com.luban.源码调试;
import com.luban.源码调试.config.AppConfig;
import com.luban.源码调试.dao.UserMapper;
import com.luban.源码调试.dao.controller;
import com.luban.源码调试.postprocessor.BeanDefinitionRegistryPostProcessorImple111;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class test {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
// annotationConfigApplicationContext.addBeanFactoryPostProcessor(new BeanDefinitionRegistryPostProcessorImple111());
// annotationConfigApplicationContext.register(AppConfig.class);
// annotationConfigApplicationContext.refresh();
// controller controller1 = (controller) annotationConfigApplicationContext.getBean("controller");
// controller1.controller();
UserMapper user = (UserMapper) annotationConfigApplicationContext.getBean("UserMapper");
System.out.println(user.getUser());
}
}
思路:
MyImportBeanDefinitionRegister实现ImportBeanDefinitionRegistrar,作用是读取到对应的mapper接口,然后将接口转成一个bean,同时设置bean对应的calss为某个实现了factoryBean接口的类,假设为A。A里面里面可以拿到对应的mapper接口,然后为这个接口生成一个代理类,最终生成的代理类,调用对应mapper中对应的方法,就能够实现数据库查询了。
最终MyImportBeanDefinitionRegister会把这个bean注册到bean工厂里面。完成整个注册过程。