如何动态在spring mvc中增加bean
阅读对象##
搭框架人员,或者其他感兴趣的开发人员
背景##
一般来说在业务代码中,加上 @Component, @Service,@Repository, @Controller等注解就可以实现将bean注册到Spring中了。
但是在写框架,可能有些类会动态生成,怎么动态注册到Spring中呢?
BeanDefinitionRegistryPostProcessor 接口##
BeanDefinitionRegistryPostProcessor接口是一个可以修改spring工厂中已定义的bean的接口,该接口有个postProcessBeanDefinitionRegistry方法。
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* [@param](https://my.oschina.net/u/2303379) registry the bean definition registry used by the application context
* [@throws](https://my.oschina.net/throws) org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
实现##
代码###
public class App implements BeanDefinitionRegistryPostProcessor{
@Override
public void postProcessBeanDefinitionRegistry(
BeanDefinitionRegistry registry) throws BeansException {
registry.registerBeanDefinition("demoEntityDao", getDefinition(AcAlert.class));
}
private BeanDefinition getDefinition(Class<?> cls) {
DaoInterfaceGenerator g = new DaoInterfaceGenerator(cls);
Class<?> daoClass = g.generateClass();
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClass(MapperFactoryBean.class);
bd.getConstructorArgumentValues().addGenericArgumentValue(daoClass);
bd.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference("sqlSessionFactory"));
return bd;
}
}
步骤说明###
- 实现
BeanDefinitionRegistryPostProcessor接口 - 处理
postProcessBeanDefinitionRegistry方法 - 生成
BeanDefinition,上面展示了动态添加一个mybatis Dao的bean注册过程
我遇到的坑##
当动态生成生成mybatis的dao接口时,报这个错误:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demoEntityDao': Post-processing of FactoryBean's singleton object failed; nested exception is java.lang.IllegalArgumentException: interface com.dhcc.ac.domain.AcAlertDao is not visible from class loader
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:116)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1590)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:254)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1054)
at com.dhcc.framework.App.main(App.java:48)
Caused by: java.lang.IllegalArgumentException: interface com.dhcc.ac.domain.AcAlertDao is not visible from class loader
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:581)
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:557)
at java.lang.reflect.WeakCache$Factory.get(WeakCache.java:230)
at java.lang.reflect.WeakCache.get(WeakCache.java:127)
at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:419)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:719)
at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:121)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
at org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor.postProcessAfterInitialization(AbstractAdvisingBeanPostProcessor.java:90)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1723)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:113)
... 5 more
错误原因在于动态生成的class加载的classloader,与Proxy.newProxyInstance使用的ClassLoader,不是同一个classloader,所以在Proxy.newProxyInstance找不到这个新生成的类。
解决办法###
动态加载类,一般都是用defineClass动态加载到ClassLoader里去。
但defineClass不是public,所以在这里卡了一段时间。
后来,突然之间找到了解决办法,使用反射调用defineClass就好了呀。
小结##
技术没什么高深的,我后面将要写的一个功能,用到了本篇的技术,这里先介绍一下。
我的微信zouhaibin294148,不知不觉写了10多年代码了

如何动态在spring mvc中增加bean的更多相关文章
- Spring mvc 中使用 kaptcha 验证码
生成验证码的方式有很多,个人认为较为灵活方便的是Kaptcha ,他是基于SimpleCaptcha的开源项目.使用Kaptcha 生成验证码十分简单并且参数可以进行自定义.只需添加jar包配置下就可 ...
- 7 -- Spring的基本用法 -- 5... Spring容器中的Bean;容器中Bean的作用域;配置依赖;
7.5 Spring容器中的Bean 7.5.1 Bean的基本定义和Bean别名 <beans.../>元素是Spring配置文件的根元素,该元素可以指定如下属性: default-la ...
- Spring MVC 中的http Caching
文章目录 过期时间 Last-Modified ETag Spring ETag filter Spring MVC 中的http Caching Cache 是HTTP协议中的一个非常重要的功能,使 ...
- spring mvc中使用freemark的一点心得
参考文档: FreeMarker标签与使用 连接http://blog.csdn.net/nengyu/article/details/6829244 freemarker学习笔记--指令参考: ht ...
- Spring MVC中处理静态资源的多种方法
处理静态资源,我想这可能是框架搭建完成之后Web开发的”头等大事“了. 因为一个网站的显示肯定会依赖各种资源:脚本.图片等,那么问题来了,如何在页面中请求这些静态资源呢? 还记得Spring MVC中 ...
- 解决spring配置中的bean类型的问题:BeanNotOfRequiredTypeException
解决spring配置中的bean类型的问题:BeanNotOfRequiredTypeException这个问题出现的原因:一般在使用annotation的方式注入spring的bean 出现的,具体 ...
- Spring MVC 中的基于注解的 Controller【转】
原文地址:http://my.oschina.net/abian/blog/128028 终于来到了基于注解的 Spring MVC 了.之前我们所讲到的 handler,需要根据 url 并通过 H ...
- spring mvc中的文件上传
使用commons-fileupload上传文件所需要的架包有:commons-fileupload 和common-io两个架包支持,可以到Apache官网下砸. 在配置文件spring-mvc.x ...
- spring mvc中的valid
当你希望在spring mvc中直接校验表单参数时,你可以采用如下操作: 声明Validator的方式: 1.为每一个Controller声明一个Validator @Controller publi ...
随机推荐
- 5天揭秘js高级技术-第一天
一.基础杂记 1. document.write() <script type="text/javascript"> document.write('<h2> ...
- Android之列表索引
其实这个功能是仿苹果的,但是现在大多数Android设备都已经有了这个功能,尤其是在通讯录中最为常见.先来看看今天这个DEMO的效果图(如下图):从图中我们可以看到,屏幕中的主体是一个ListView ...
- php打印中文乱码
php文档的文本格式都设置成 utf-8 格式 在代码中添加 header("content-type:text/html; charset=utf-8");
- LPC1769 CAN的自测试模式
一.背景 客户要了一块单路CAN的板子,他希望在没有其他板子的情况下进行自行测试,然后按照我写的 APP选择自收发测试选项,却无法接收到发送的信息,但是外接了一块板子就可以接收到自己发送的 信息:由于 ...
- UI第十八节——UITableView
在iOS开发中UITableView可以说是使用最广泛的控件,我们平时使用的软件中到处都可以看到它的影子,基本大部分应用都有UITableView.当然它的广泛使用自然离不开它强大的功能,今天就针对U ...
- eclipse建立springMVC 简单项目
http://jinnianshilongnian.iteye.com/blog/1594806 如何通过eclipse建立springMVC的简单项目,现在简单介绍一下. 工具/原料 eclip ...
- win10 Vmware12装mac os X10.11虚拟机教程
1.下载安装VMware 12,具体教程在网上都能看见. 2.下载mac os的镜像,最好下载cdr格式的. 3.在导入虚拟机的时候,到选择客户机操作系统的时候,没有网上出现的Mac os,如下图所示 ...
- git知识点整理
- 功能实现:PLC对LPC的音量控制
设计方案1: 在PLC上,当使用QDial调节音量时,触发QDial的SIGNAL:ValueChange(),对应SLOT向LPC发送自定义键码0x22; 在LPC上,当接收到0x22键码时,执行操 ...
- WebView随学笔记
对于WebView而言我们需要掌握的内容是: /** 学习目标:webView * 1).将WebView加入到应用中 * 2).使用WebView加载页面 * 3).获取网络访问 * 4).在Web ...