我是靠谱客的博主 善良帽子,这篇文章主要介绍mybatis动态代理和spring对象注入,现在分享给大家,希望可以做个参考。

mybatis动态代理

实现方式:jdk通过proxy()动态代理产生mapper的代理对象
1.创建一个mapper;

复制代码
1
2
3
4
5
6
7
8
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;

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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对象

复制代码
1
2
3
4
5
6
7
8
9
10
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对象的方法

复制代码
1
2
3
4
5
6
7
8
9
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(); } }

spring对象注入

第一种方式:使用@Bean注入
1.创建一个类,将mybatis动态代理产生的对象@Bean方式注入

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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注入到容器当中了;

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
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的方法;

复制代码
1
2
3
4
5
6
7
8
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的包

复制代码
1
2
3
4
5
6
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @ComponentScan("com.hnu") @Configuration public class Appconfig {}

2.创建一个对象,也可以直接使用动态代理所产生的的对象;

复制代码
1
2
3
4
5
public class Haaa { public Haaa(){ } }

3.实现 FactoryBean接口并重写方法;

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
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的配置如下;

复制代码
1
2
3
4
5
<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接口重写方法,并定义一个可传参(参数就是需要注入的对象)的构造函数;

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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的构造函数;

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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,并扫描包;

复制代码
1
2
3
4
5
6
7
8
9
10
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方法

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
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的方法。

复制代码
1
2
3
4
5
6
7
8
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();

最后

以上就是善良帽子最近收集整理的关于mybatis动态代理和spring对象注入的全部内容,更多相关mybatis动态代理和spring对象注入内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(84)

评论列表共有 0 条评论

立即
投稿
返回
顶部