`
fly0wings
  • 浏览: 35314 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring的xml配置与annotation注解混合使用无法Autowired的问题

 
阅读更多

问题:

在LVMMCrawlerSuit.java是xml配置的bean, 需要注入用@Component声明的bean. 但是运行的时候却报NullPointerException. 说明没有注入进来.

 

代码:

1. java

Java代码  收藏代码
  1. 1. LVMMCrawlerSuit.java  
  2.  public class LVMMCrawlerSuit extends AbstractCrawlerSuit{  
  3.   
  4.     @Resource  
  5.     private LVMMURLBuilder lvmmurlBuilder;  
  6.   
  7.     public LVMMCrawlerSuit() {  
  8.     }  
  9. }  
  10.   
  11. 2. LVMMURLBuilder.java  
  12. @Component  
  13. public class LVMMURLBuilder extends AbstractResourceURLBuilder {  
  14.     public LVMMURLBuilder() {    }  
  15. }  

 

2. 配置.

Xml代码  收藏代码
  1. <bean id="LVMMCrawlerSuit" class = 'com.qunar.b2c.crawlersuit.impl.LVMMCrawlerSuit'/>   

 

问题查找:

1. 查找网上资源,未果.

2. 果断debug,跟踪源码.

       将断点定位到 org.springframework.context.support.AbstractRefreshableApplicationContext#loadBeanDefinitions ,该方法是加载bean的必经之路.跟踪发现,该方法共执行两次,生成了两个不同的 org.springframework.beans.factory.support.DefaultListableBeanFactory, 并且后者的parentBeanFactory为前者,根据原设计是后者可以调用前者的bean 并完成注入.

      现在报NullPointerException,很明显是"父调用子",所以肯定拿不到.在打印的log中进行了佐证.

      在debug中发现,两次执行分别来自不同的beans资源文件: app-web.xml 和 applicationContext-*.xml, 按key查找,很容易找到了配置信息如下.

Xml代码  收藏代码
  1. <servlet>  
  2.         <servlet-name>dispatcherServlet</servlet-name>  
  3.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4.         <init-param>  
  5.             <param-name>contextConfigLocation</param-name>  
  6.             <param-value>  
  7.                 classpath:classpath:app-web.xml  
  8.             </param-value>  
  9.         </init-param>  
  10.         <load-on-startup>1</load-on-startup>  
  11.     </servlet>  
  12.   
  13.         <context-param>  
  14.         <param-name>contextConfigLocation</param-name>  
  15.         <param-value>classpath:applicationContext-*.xml</param-value>  
  16.     </context-param>  

 

    既然,两次加载,并且加载了不同的beans,虽然有父子的层级关系,但是限制多多. 那么就尝试合二为一.

    在test中,发现因为修改了spring默认加载的文件名,所以删除任何一个配置都不能正确运行.那么就全部设置成一样的吧. test success......

 

解决方案:

    方案一. 将配置文件路径合并, 分别指定给不同配置.

Xml代码  收藏代码
  1. <servlet>  
  2.         <servlet-name>dispatcherServlet</servlet-name>  
  3.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4.         <init-param>  
  5.             <param-name>contextConfigLocation</param-name>  
  6.             <param-value>  
  7.                 classpath:applicationContext-*.xml,classpath:app-web.xml  
  8.             </param-value>  
  9.         </init-param>  
  10.         <load-on-startup>1</load-on-startup>  
  11.     </servlet>  
  12.   
  13.         <context-param>  
  14.         <param-name>contextConfigLocation</param-name>  
  15.         <param-value>classpath:applicationContext-*.xml,classpath:app-web.xml</param-value>  
  16.     </context-param>  

 

 

    方案二. 原有配置不变,合理规划Bean的定义及合理使用.

         在方案一中, 使用的简单,粗暴的解决办法. 没有考虑到spring的设计思想. 既然有ioc容器的父子级划分,那么在使用的时候,一定会有用的.

         在使用annotation定义bean 的时候,是需要增加如下代码,对使用何种注解的类才管理到ioc容器中.

 

Xml代码  收藏代码
  1. <context:component-scan base-package="com.qunar.b2c">  
  2.        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />  
  3.        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />  
  4.        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />  
  5.        <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" />  
  6.    </context:component-scan>  

 

        上述提到, 在 spring web的使用中, 会加载两个ioc容器,

          1. 一个是contextConfigLocation定义,用来启动spring核心框架的. 所以在该步骤中,应加载应用中的基础服务信息的bean,如 dao,Service 等等.

          2. 另外一个ioc容器是web加载的容器, 那么只需加载Controller相关的bean.

        因为在spring ioc的 DefaultListableBeanFactory类是支持父子关系,

            1. 子容器是可以访问到父容器中的bean,

            2. 然而父容器访问不了子容器的bean,

        这就保证了, Controller可以访问 Service等, 但是Service 访问不了web层的bean, 这样就将职责分开了.所以修改的配置如下:

 

Xml代码  收藏代码
  1. applicationContext-beans.xml:  
  2.   
  3. <context:component-scan base-package="com.qunar.b2c">  
  4.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />  
  5.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />  
  6.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" />  
  7.     </context:component-scan>  
  8.   
  9. app-web.xml  
  10.   
  11.  <context:component-scan base-package="com.qunar.b2c">  
  12.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />  
  13.    </context:component-scan>  

 

     在开发定义bean的时候, 也需要注意,把bean定义到哪一层级.

分享到:
评论

相关推荐

    spring annotation注解

    Spring Annotation 注解 Spring 框架中的注解是用于在 Java 类中添加元数据的,通过这些元数据,Spring 框架可以在运行时提供更多的功能。 Spring 框架提供了多种类型的注解,例如 @Autowired、@Resource、@...

    Spring的Autowired自动装配(XML版本+Annotation版本+源码+解析)

    在Spring框架中,@Autowired不仅提供了方便的依赖注入,还与其他注解(如@Service、@Repository、@Component、@Controller等)一起构成了强大的组件模型,使得应用程序的组件更加松耦合,易于测试和维护。...

    学习Spring笔记_Annotation(注解)_Component

    4. **注解配置与XML配置的对比**:Spring框架既支持XML配置也支持注解配置。XML配置方式直观,但代码量大,维护困难;注解配置简洁,减少了XML配置文件,使代码更加清晰,同时提高了可读性和可维护性。然而,对于...

    Spring demo 自动检测注解

    在Spring框架中,自动检测注解(Autowired)是核心特性之一,它极大地简化了依赖注入的过程,使得开发者能够更加专注于业务逻辑,而不是繁琐的配置。本文将深入探讨Spring中的自动检测注解及其工作原理。 首先,`@...

    Spring的Annotation配置相关讲义

    在Spring框架中,Annotation配置是一种简洁且强大的方式来管理Bean的定义和依赖注入,它消除了传统的XML配置文件,使得代码更加简洁、易读。在Spring 3.0及以上版本中,Annotation配置得到了广泛的应用。 首先,...

    spring autowired注解完整版

    **@Autowired 与 @ComponentScan**:在 XML 配置中,&lt;context:component-scan&gt; 标签用于扫描指定包及其子包下的类,寻找使用了 @Component、@Service、@Repository 和 @Controller 等注解的类,这些类会被注册为 ...

    Spring Annotation (注解)详解

    Spring注解是Spring框架中的一种核心特性,它允许开发者在Java源代码中嵌入元数据,简化了XML配置,提高了代码的可读性和维护性。从Spring 2.5开始,注解成为主流配置方式,提供了更加简洁和直观的Bean定义和依赖...

    Spring IOC之基于注解的容器配置.docx

    Spring框架允许开发者灵活地选择注解或XML配置,甚至可以混合使用。通过`&lt;context:annotation-config/&gt;`元素,可以在XML配置中启用注解驱动的配置,它会自动注册相关的Bean后处理器,如@...

    Dwr3+Spring3 全注解 annotation 方式

    3. **配置DWR**:在`dwr.xml`配置文件中,可以使用`&lt;create&gt;`标签手动配置可远程访问的Java类,但在全注解方式下,这部分配置可以省略,因为Spring会自动处理。 4. **注解Java类**:在需要暴露给DWR的Java类上使用`...

    如何完成spring的最小化XML配置

    然而,随着框架的发展,为了简化配置,Spring引入了最小化XML配置的概念,以及注解装配的方式,使得配置更加简洁和高效。本文将深入探讨如何实现Spring的最小化XML配置。 一、自动装配 1. 四种类型的自动装配 - ...

    Spring基于注释(Annotation)的配置.pdf

    2. **创建Spring配置文件**:编写XML配置文件或使用Java配置类来定义Bean和其依赖关系。 3. **使用注解**:在需要注入的地方添加适当的注解,如`@Autowired`、`@Resource`等。 4. **配置处理器**:对于`@Autowired...

    Spring Annotation简介一

    Spring Annotation的引入主要是为了解决XML配置的繁琐问题。在传统的Spring应用中,大量的bean配置信息存储在XML文件中,这不仅增加了配置文件的复杂性,也使得代码与配置分离,降低了代码的直观性。Spring ...

    Spring标注(Annotation)的使用

    随着技术的发展,Spring引入了注解(Annotation),极大地简化了配置,使得代码更加简洁、易读。这篇文档将深入探讨Spring注解的使用,包括它们如何工作以及如何在实际项目中应用。 首先,让我们了解Spring的核心...

    Spring系列之Spring常用注解总结1

    本文主要讨论Spring中的@Autowired注解,以及如何通过注解实现依赖注入,从而避免了在.java和.xml文件间频繁切换的问题。 首先,让我们回顾一下传统的Spring配置方式。在不使用注解的情况下,我们需要在.xml文件中...

    ssh2 Annotation注解 框架+oracle

    **Spring Annotation注解** Spring框架允许开发者使用注解来声明Bean、依赖注入、事务管理等。例如: - `@Component`、`@Service`、`@Repository`和`@Controller`注解用于标记组件类,使它们成为Spring容器的一部分...

    spring注解完整版[定义].pdf

    Spring 2.5引入了@Autowired注解,它极大地简化了配置,允许开发者在不编写XML配置文件的情况下完成bean的自动装配。本文将深入探讨@Autowired注解以及如何在Spring中使用它。 @Autowired注解的主要作用是自动将所...

    SSH2 annotation 实现struts2.1.6 spring2.5.6 hibernate3.3 全注解开发

    在这个特定的项目中,开发者选择了SSH2的特定版本:Struts2.1.6、Spring2.5.6和Hibernate3.3,并且强调了全注解开发,这意味着在配置文件中尽可能地使用注解来代替XML配置。 首先,让我们详细了解一下这三个框架的...

    Spring annotation

    Spring注解的使用大大减少了XML配置,提高了代码的可读性和维护性。理解并熟练运用这些注解是每个Spring开发者必备的技能。在实际开发中,根据项目需求选择合适的注解,可以有效地组织和管理代码,提升开发效率。

Global site tag (gtag.js) - Google Analytics