- 浏览: 643120 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
hsluoyz:
现在新推出了一个权限框架,叫jCasbin(https://g ...
Shiro 权限框架使用总结 -
飕飕飞:
比如说 我用私匙加密一段数据,并加密成功。那签名时用什么生成的 ...
Java使用RSA加密解密签名及校验 -
文艺吧网:
楼主讲的好详细,这里有整套 Shiro demo http:/ ...
Shiro 权限框架使用总结 -
nanshanmu:
333引用[url][*]||||[/flash][/flas ...
SpringMVC中返回值处理 -
变脸小伙:
) 业务类在Spring配置 ...
整合Struts2与Spring以及spring的自动装配
问题
如下方式可以成功扫描到@Controller注解的Bean,不会扫描@Service/@Repository的Bean。正确
Java代码 收藏代码
<context:component-scan base-package="org.bdp.system.test.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
但是如下方式,不仅仅扫描@Controller,还扫描@Service/@Repository的Bean,可能造成一些问题
Java代码 收藏代码
<context:component-scan base-package="org.bdp">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
这个尤其在springmvc+spring+hibernate等集成时最容易出问题的地,最典型的错误就是:
事务不起作用
这是什么问题呢?
分析
1、<context:component-scan>会交给org.springframework.context.config.ContextNamespaceHandler处理;
Java代码 收藏代码
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
2、ComponentScanBeanDefinitionParser会读取配置文件信息并组装成org.springframework.context.annotation.ClassPathBeanDefinitionScanner进行处理;
3、如果没有配置<context:component-scan>的use-default-filters属性,则默认为true,在创建ClassPathBeanDefinitionScanner时会根据use-default-filters是否为true来调用如下代码:
Java代码 收藏代码
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) cl.loadClass("javax.annotation.ManagedBean")), false));
logger.info("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) cl.loadClass("javax.inject.Named")), false));
logger.info("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
可以看到默认ClassPathBeanDefinitionScanner会自动注册对@Component、@ManagedBean、@Named注解的Bean进行扫描。如果细心,到此我们就找到问题根源了。
4、在进行扫描时会通过include-filter/exclude-filter来判断你的Bean类是否是合法的:
Java代码 收藏代码
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
if (!metadata.isAnnotated(Profile.class.getName())) {
return true;
}
AnnotationAttributes profile = MetadataUtils.attributesFor(metadata, Profile.class);
return this.environment.acceptsProfiles(profile.getStringArray("value"));
}
}
return false;
}
即
首先通过exclude-filter 进行黑名单过滤;
然后通过include-filter 进行白名单过滤;
否则默认排除。
结论
Java代码 收藏代码
<context:component-scan base-package="org.bdp">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
为什么这段代码不仅仅扫描@Controller注解的Bean,而且还扫描了@Component的子注解@Service、@Reposity。因为use-default-filters默认为true。所以如果不需要默认的,则use-default-filters=“false”禁用掉。
请参考
《SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常见问题总结》
《第三章 DispatcherServlet详解 ——跟开涛学SpringMVC》中的ContextLoaderListener初始化的上下文和DispatcherServlet初始化的上下文关系。
如果在springmvc配置文件,不使用cn.javass.demo.web.controller前缀,而是使用cn.javass.demo,则service、dao层的bean可能也重新加载了,但事务的AOP代理没有配置在springmvc配置文件中,从而造成新加载的bean覆盖了老的bean,造成事务失效。只要使用use-default-filters=“false”禁用掉默认的行为就可以了。
问题不难,spring使用上的问题。总结一下方便再遇到类似问题的朋友参考。
如下方式可以成功扫描到@Controller注解的Bean,不会扫描@Service/@Repository的Bean。正确
Java代码 收藏代码
<context:component-scan base-package="org.bdp.system.test.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
但是如下方式,不仅仅扫描@Controller,还扫描@Service/@Repository的Bean,可能造成一些问题
Java代码 收藏代码
<context:component-scan base-package="org.bdp">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
这个尤其在springmvc+spring+hibernate等集成时最容易出问题的地,最典型的错误就是:
事务不起作用
这是什么问题呢?
分析
1、<context:component-scan>会交给org.springframework.context.config.ContextNamespaceHandler处理;
Java代码 收藏代码
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
2、ComponentScanBeanDefinitionParser会读取配置文件信息并组装成org.springframework.context.annotation.ClassPathBeanDefinitionScanner进行处理;
3、如果没有配置<context:component-scan>的use-default-filters属性,则默认为true,在创建ClassPathBeanDefinitionScanner时会根据use-default-filters是否为true来调用如下代码:
Java代码 收藏代码
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) cl.loadClass("javax.annotation.ManagedBean")), false));
logger.info("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) cl.loadClass("javax.inject.Named")), false));
logger.info("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
可以看到默认ClassPathBeanDefinitionScanner会自动注册对@Component、@ManagedBean、@Named注解的Bean进行扫描。如果细心,到此我们就找到问题根源了。
4、在进行扫描时会通过include-filter/exclude-filter来判断你的Bean类是否是合法的:
Java代码 收藏代码
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
if (!metadata.isAnnotated(Profile.class.getName())) {
return true;
}
AnnotationAttributes profile = MetadataUtils.attributesFor(metadata, Profile.class);
return this.environment.acceptsProfiles(profile.getStringArray("value"));
}
}
return false;
}
即
首先通过exclude-filter 进行黑名单过滤;
然后通过include-filter 进行白名单过滤;
否则默认排除。
结论
Java代码 收藏代码
<context:component-scan base-package="org.bdp">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
为什么这段代码不仅仅扫描@Controller注解的Bean,而且还扫描了@Component的子注解@Service、@Reposity。因为use-default-filters默认为true。所以如果不需要默认的,则use-default-filters=“false”禁用掉。
请参考
《SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常见问题总结》
《第三章 DispatcherServlet详解 ——跟开涛学SpringMVC》中的ContextLoaderListener初始化的上下文和DispatcherServlet初始化的上下文关系。
如果在springmvc配置文件,不使用cn.javass.demo.web.controller前缀,而是使用cn.javass.demo,则service、dao层的bean可能也重新加载了,但事务的AOP代理没有配置在springmvc配置文件中,从而造成新加载的bean覆盖了老的bean,造成事务失效。只要使用use-default-filters=“false”禁用掉默认的行为就可以了。
问题不难,spring使用上的问题。总结一下方便再遇到类似问题的朋友参考。
发表评论
-
MongoDB Java Driver操作指南
2015-08-04 21:42 2611MongoDB为Java提供了非常丰富的API操作,相比关系 ... -
Spring3自定义环境配置 <beans profile="">
2015-04-22 10:51 1318摘自springside3 Spring 3.1的功能 ... -
json-rpc 1.0规范解读
2015-04-17 14:21 1360JSON可能是这个地球上 ... -
request.getParameter()、request.getInputStream()和request.getReader()
2015-03-30 11:16 3042大家经常 用servlet和jsp, ... -
微信企业号上传下载多媒体文件接口详解演示-java
2015-03-27 15:37 6403企业在使用接口时,对多媒体文件、多媒体消息的获取和调用等操作 ... -
java如何得到GET和POST请求URL和参数列表
2015-03-13 16:28 3168在servlet中GET请求可以通过HttpServletR ... -
关于<context:property-placeholder>的一个有趣现象
2015-01-05 20:09 653先来看下A和B两个模块 A模块和B模块都分别拥有自己的S ... -
spring jms _ activemq
2015-01-05 13:50 961参考链接: http://bsnyderblog.blogsp ... -
读取配置信息
2014-12-29 18:08 914第一种方法是使用java.io和java.util包,缺点是路 ... -
spring 事件机制
2014-11-14 14:17 1012在Spring中已经定义的五 ... -
spring InitializingBean接口
2014-10-27 01:33 673最近工作需要得到sping中的每个事物需要执行的sql, ... -
spring InitializingBean接口
2014-10-27 01:33 1005最近工作需要得到sping中的每个事物需要执行的sql,称 ... -
四种常见的 POST 提交数据方式
2014-09-23 11:38 1680HTTP/1.1 协议规定的 HTTP 请求方法有 OPT ... -
使用 Java 配置进行 Spring bean 管理
2014-07-31 17:58 886Spring bean 是使用传统的 XML 方法配置的。在 ... -
怎么使用Servlet 3.0中的上传文件呢?
2014-07-31 15:20 976Spring 3.1开始提供了Servlet 3.0的支持。 ... -
Spring mvc 拓展使用
2014-07-31 15:08 1016原文链接:http://my.oschina.net/u/11 ... -
Spring MVC handler method 参数绑定常用的注解
2014-07-31 10:36 2062参考链接:http://csjava.bl ... -
SpringMVC中使用Interceptor拦截器
2014-06-30 15:18 888SpringMVC 中的Interceptor 拦 ... -
AOP的底层实现-CGLIB动态代理和JDK动态代理
2014-05-04 16:58 1079AOP是目前Spring框架中的 ... -
Spring AOP 实现原理与 CGLIB 应用
2014-05-04 16:39 763AOP(Aspect Orient Programmi ...
相关推荐
<context:component-scan/>标签提供了 use-default-filters 属性,该属性控制着是否使用默认的过滤器。默认情况下,use-default-filters 属性为 true,即使用默认的过滤器。如果将其设置为 false,则需要手动配置...
<context:component-scan base-package="leot.test" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> <context:include-filter ...
<context:component-scan base-package="com.mvc.web" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component...
<context:component-scan> 标签有一个 use-default-filters 属性,该属性默认为 true,这意味着会扫描指定包下的全部的标有 @Component 的类,并注册成 Bean。因此,如果仅仅是在配置文件中这么写 <context:...
<context:component-scan base-package="org.bc.redis.service" use-default-filters="true"> </context:component-scan> ``` SpringMVC 的配置文件 springmvc.xml: ``` <context:component-scan base-package="org...
在使用<context:component-scan/>元素时,可以使用base-package属性指定需要扫描的基类包,resource-pattern属性可以用来过滤特定的类。如果需要扫描多个包,可以使用逗号分隔。 示例:<context:component-scan ...
<context:component-scan base-package="com.dn" use-default-filters="false"> <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/> </context:component-scan>...
在Spring MVC框架中,注解自动扫描是核心特性之一,它允许开发者通过在类或方法上使用特定注解(如@Controller、@Service、@Repository等)来声明组件,然后由Spring容器自动检测并管理这些组件。然而,在实际开发中...
<context:component-scan base-package="com.sishuok.es" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.ControllerAdvice"/> </context:...
Not Using Commons Logging ................................................................... 12 Using SLF4J ..............................................................................................
Not Using Commons Logging ................................................................... 12 Using SLF4J ..............................................................................................