实现方式:jdk通过proxy()动态代理产生mapper的代理对象
1.创建一个mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
public interface FriendMapper {
@Select("select *from tb_friend")
public List<Map<String,Object>> query();
}
2.重写 InvocationHandler的invoke方法
invoke里面包括获取sql,解析sql;
import org.apache.ibatis.annotations.Select;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class HnuInvohander implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取sql
Select a= method.getAnnotation(Select.class);
String sql=a.value()[0];
//解析sql....
System.out.println("sql----"+sql);
return null;
}
}
3.使用Proxy创建object对象
newProxyInstance有三个参数,第一个Class对象的类装载器,第二个“类”类型数组,第三个产生一个HnuInvohander对象
import java.lang.reflect.Proxy;
public class HnuSession {
public static Object getMapper(Class clazz){
Class []clazzs=new Class[]{clazz};
Object object=Proxy.newProxyInstance(HnuSession.class.getClassLoader(),clazzs,new HnuInvohander());
return object;
}
}
4.测试,调用object对象的方法
import com.hnu.mapper.FriendMapper;
import com.hnu.mybatis.HnuSession;
public class Test {
public static void main(String[] args) {
FriendMapper friendMapper= (FriendMapper) HnuSession.getMapper(FriendMapper.class);
friendMapper.query();
}
}
第一种方式:使用@Bean注入
1.创建一个类,将mybatis动态代理产生的对象@Bean方式注入
import com.hnu.mapper.FriendMapper;
import com.hnu.mybatis.HnuSession;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ComponentScan("com.hnu")
@Configuration
public class Appconfig {
@Bean
public FriendMapper friendMapper(){
FriendMapper friendMapper= (FriendMapper) HnuSession.getMapper(FriendMapper.class);
return friendMapper;
}
}
2.创建Service类,调用friendMapper方法,此时已经使用@Bean方式将friendMapper注入到容器当中了;
import com.hnu.mapper.FriendMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class FriendService {
@Autowired
FriendMapper friendMapper;
public void queryAll(){
friendMapper.query();
}
}
3.测试,在容器中使用Service的方法;
import com.hnu.app.Appconfig;
import com.hnu.service.FriendService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(Appconfig.class);
ac.getBean(FriendService.class).queryAll();
第二种方法:实现FactoryBean接口,它会返回两个bean对象
一个是实现接口的类本身,另一个重写方法所产生的的对象
1.扫描com.hnu中带有@Component的包
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ComponentScan("com.hnu")
@Configuration
public class Appconfig {}
2.创建一个对象,也可以直接使用动态代理所产生的的对象;
public class Haaa {
public Haaa(){
}
}
3.实现 FactoryBean接口并重写方法;
import com.hnu.service.Haaa;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
@Component
public class CJFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new Haaa();
}
@Override
public Class<?> getObjectType() {
//可以在这里直接使用动态代理产生的对象
// FriendMapper friendMapper= (FriendMapper) HnuSession.getMapper(FriendMapper.class);
//return friendMapper.class;
return Haaa.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
4.测试,在容器中获取产生的bean。
import com.hnu.app.Appconfig;
import com.hnu.service.Haaa;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(Appconfig.class);
System.out.println(ac.getBean("CJFactoryBean"));
System.out.println(ac.getBean("&CJFactoryBean"));
System.out.println(ac.getBean(Haaa.class));
}
}
第三种方式
spring中bean的注入方式也是采用这种方法,一般spring的bean的配置如下;
<bean id="FridendMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface"value="com.hnu.mapper.FriendMapper">
</property>
</bean>
下面就是模拟spring注入bean:
实例化对象:
普通类实例化方式:class–>new
spring实例化方式:class–>scan扫描–>BeanDefinnition的方法–>生成map–>遍历map–>new bean
具体实现:通过实现FactoryBean和ImportBeanDefinitionRegistrar接口
1.实现FactoryBean接口重写方法,并定义一个可传参(参数就是需要注入的对象)的构造函数;
import org.springframework.beans.factory.FactoryBean;
public class CJFactoryBean implements FactoryBean {
Class mapperInterface;
public CJFactoryBean(Class mapperInterface){
this.mapperInterface=mapperInterface;
}
@Override
public Object getObject() throws Exception {
Object object= HnuSession.getMapper(mapperInterface);
return object;
}
@Override
public Class<?> getObjectType() {
return mapperInterface;
}
@Override
public boolean isSingleton() {
return false;
}
}
2.实现ImportBeanDefinitionRegistrar接口重写方法,BeanDefinition方法中有很多管理对象的方法,此处是指定生成一个对象,并将它传给CJFactoryBean的构造函数;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class CJImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
//指定构造方法的参数
BeanDefinitionBuilder builder=BeanDefinitionBuilder.genericBeanDefinition(CJFactoryBean.class);
AbstractBeanDefinition beanDefinition= builder.getBeanDefinition();
//传入的mapper都可以通过遍历循环产生
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("com.hnu.mapper.FriendMapper");
beanDefinitionRegistry.registerBeanDefinition("CJFactoryBean",beanDefinition);
}
}
3.创建一个类,导入识别CJImportBeanDefinitionRegistrar.class,并扫描包;
import com.hnu.mybatis.CJImportBeanDefinitionRegistrar;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ComponentScan("com.hnu")
@Configuration
@Import(CJImportBeanDefinitionRegistrar.class)
public class Appconfig {
}
4.创建Service类,调用friendMapper方法
import com.hnu.mapper.FriendMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class FriendService {
@Autowired
FriendMapper friendMapper;
public void queryAll(){
friendMapper.query();
}
}
5.在容器中使用Service的方法。
import com.hnu.app.Appconfig;
import com.hnu.service.FriendService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(Appconfig.class);
ac.getBean(FriendService.class).queryAll();