`
jokze
  • 浏览: 3061 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

spring中注入内部类

阅读更多

在spring中注入内部类,有可能会遇到如下异常信息:

2014-5-1421:52:45 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息:Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1c56c60: startup date [WedMay1421:52:45 CST 2014]; root of context hierarchy
2014-5-1421:52:45 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息:Loading XML bean definitions fromclass path resource [spring.xml]2014-5-1421:52:46 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息:Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@7244ca: defining beans [person]; root of factory hierarchy
2014-5-1421:52:46 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
信息:Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@7244ca: defining beans [person]; root of factory hierarchy
Exceptionin thread "main" org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'person'definedinclass path resource [spring.xml]:Cannot create inner bean 'cn.outofmemory.spring.Person$Hand#ab7165' of type [cn.outofmemory.spring.Person$Hand]while setting bean property'hands'with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'cn.outofmemory.spring.Person$Hand#ab7165'definedinclass path resource [spring.xml]:Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException:Couldnot instantiate bean class[cn.outofmemory.spring.Person$Hand]:Nodefault constructor found; nested exception is java.lang.NoSuchMethodException: cn.outofmemory.spring.Person$Hand.<init>()
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:281)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:120)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:353)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:153)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
	at cn.outofmemory.spring.App.main(App.java:14)Causedby: org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'cn.outofmemory.spring.Person$Hand#ab7165'definedinclass path resource [spring.xml]:Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException:Couldnot instantiate bean class[cn.outofmemory.spring.Person$Hand]:Nodefault constructor found; nested exception is java.lang.NoSuchMethodException: cn.outofmemory.spring.Person$Hand.<init>()
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:965)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:270)...17 more
Causedby: org.springframework.beans.BeanInstantiationException:Couldnot instantiate bean class[cn.outofmemory.spring.Person$Hand]:Nodefault constructor found; nested exception is java.lang.NoSuchMethodException: cn.outofmemory.spring.Person$Hand.<init>()
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:70)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:958)...21 more
Causedby: java.lang.NoSuchMethodException: cn.outofmemory.spring.Person$Hand.<init>()
	at java.lang.Class.getConstructor0(Class.java:2715)
	at java.lang.Class.getDeclaredConstructor(Class.java:1987)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:65)...22 more

这个异常信息很长,他的意思是说我们没有给内部类指定构造函数,我们看下我们的代码和spring配置文件:

我们定义了一个Person类,这个类中有一个内部类Hand,Person类有一个hands的属性的类型是内部类数组

package cn.outofmemory.spring;publicclassPerson{privateHand[] hands;publicHand[] getHands(){return hands;}publicvoid setHands(Hand[] hands){this.hands = hands;}publicclassHand{privateint strength;publicint getStrength(){return strength;}publicvoid setStrength(int strength){this.strength = strength;}}}

我们的spring配置文件如下:

<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd"><beanclass="cn.outofmemory.spring.Person"id="person"><propertyname="hands"><list><beanclass="cn.outofmemory.spring.Person$Hand"><propertyname="strength"value="90"/></bean></list></property></bean></beans>

配置文件很简单,内部类的类名由外部类的全称+$+内部类的名称,这是无疑的。

内部类注入方式一:添加内部类默认构造函数参数

我们遇到上面的错误是因为非静态的内部类默认的构造函数有一个参数,这个参数指向其外部类的实例,所以我们需要给此内部类的bean添加constructor-arg节点,并指向外部类即可,我们修改下配置文件:

<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd"><beanclass="cn.outofmemory.spring.Person"id="person"><propertyname="hands"><list><beanclass="cn.outofmemory.spring.Person$Hand"><constructor-argref="person"></constructor-arg><propertyname="strength"value="90"/></bean></list></property></bean></beans>

App类代码如下:

package cn.outofmemory.spring;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/**
 * Hello  spring from OutOfMemory.CN
 *
 */publicclassApp 
{
    publicstaticvoid main(String[] args )
    {
        ApplicationContext appContext =newClassPathXmlApplicationContext("/spring.xml");
        Person person = appContext.getBean(Person.class);
        for(Person.Hand hand : person.getHands()){
        	System.out.println("hand strength is "+ hand.getStrength());
        }
    }}

App类的main方法获得spring中定义的person类,然后打印每一个hand的strength属性。输出如下:

hand strength is90

内部类注入方式二:将内部类修改为static

对于内部类,如果没必要访问外部类,我们可以将其定义为static的,这样在spring配置文件中配置时,就不需要设置默认构造函数了。

如下修改后的Person类:

package cn.outofmemory.spring;publicclassPerson{privateHand[] hands;publicHand[] getHands(){return hands;}publicvoid setHands(Hand[] hands){this.hands = hands;}publicstaticclassHand{privateint strength;publicint getStrength(){return strength;}publicvoid setStrength(int strength){this.strength = strength;}}}

修改后的spring配置文件:

<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd"><beanclass="cn.outofmemory.spring.Person"id="person"><propertyname="hands"><list><beanclass="cn.outofmemory.spring.Person$Hand"><propertyname="strength"value="90"/></bean></list></property></bean></beans>

App类保持不变,我们再次运行程序,依然会得到如下的输出结果:

hand strength is90

总结:

对于内部类的注入,要注意非静态内部类,其默认构造函数有一个参数,是其外部类的实例,记住这一点在spring中定义内部类就没有问题了。

如果内部类不需要访问外部类的实例,可以将其定义为static的,这样也就不需要额外的构造函数参数设置了。

Mybatis中也是同样的道理。

 

转自:http://outofmemory.cn/java/spring/spring-DI-inner-class

分享到:
评论

相关推荐

    Spring依赖注入使用构造设注入demo

    依赖注入允许我们不在类内部创建对象,而是通过外部源(如Spring容器)将依赖的对象传递给类。这样,类只需要关注自身的业务逻辑,而无需关心依赖的实现细节。 构造器注入是DI的一种形式,它通过类的构造函数传递...

    spring依赖注入例子

    Spring框架的依赖注入(Dependency Injection,简称DI)是其核心特性之一,它使得对象之间的关系在运行时由Spring容器管理,而不是硬编码在类内部。这样可以提高代码的可测试性和可维护性,因为对象的依赖关系变得松...

    Spring的注入方式详解

    Spring 框架是 Java 开发中非常重要的一个组件,它提供了一种强大的依赖注入(Dependency Injection,简称 DI)机制,使得对象之间的依赖关系可以通过配置文件或者注解来管理,而不是硬编码在类的内部。这有助于提高...

    Spring中的方法注入

    在Spring框架中,方法注入是一种非传统的依赖注入形式,它允许我们通过调用对象的方法来设置其内部状态或执行特定操作。这种方法通常用于在对象初始化之后或者在某些特定时刻注入依赖,而不是在构造函数中。下面我们...

    spring 设值注入

    `@Value` 注解可以直接在字段上使用,或者像这样在方法内部使用,将值注入到bean的属性中。 在`demo`这个项目中,可能包含了实现上述注入方式的代码示例。可能包括了 `ExampleBean` 类,以及相应的XML或Java配置...

    Spring Ioc 注解 依赖注入

    - **依赖注入**:依赖注入是一种设计模式,通过依赖注入,一个类的对象不再负责创建其依赖的对象,而是由外部容器(Spring容器)来负责创建这些依赖并注入到需要它们的地方。 #### 三、Spring IoC容器的工作原理 ...

    spring注入文件写法

    综上所述,Spring注入文件的写法涉及了数据源、Hibernate集成、事务管理和DAO的声明及配置。通过这种方式,Spring能够提供一个灵活且强大的基础设施,支持数据库操作和事务管理,同时保持代码的整洁和模块化。

    spring依赖注入基础知识.rar

    Spring依赖注入(Dependency Injection,简称DI)是Spring框架的核心特性之一,它允许对象之间的依赖关系在运行时由外部容器管理,而不是由代码内部硬编码。这样可以提高代码的可测试性、可维护性和松耦合性。下面...

    Spring - -setter方式 向bean中注入各种类型的值

    8. **源码分析**:标签中的"源码"可能意味着博主还深入解析了Spring框架中setter注入的相关源代码,解释了内部的工作原理,如BeanDefinition、PropertyValues、BeanWrapper等概念。 9. **工具使用**:"工具"标签...

    spring工厂属性注入

    // someDependency是已经由Spring注入的依赖 return businessObject; } ``` 通过这种方式,即使对象的创建涉及到复杂的逻辑,Spring也能通过工厂bean进行控制并管理对象的生命周期,同时保持属性注入的能力。在...

    使用xml和annotation实现类似spring依赖注入和自动扫描类的功能

    首先,依赖注入是面向对象设计中的一个重要概念,它允许我们在运行时动态地将依赖关系传递给对象,而不是在对象内部硬编码这些依赖。这样可以提高代码的可测试性和灵活性。在Spring框架中,依赖注入可以通过XML配置...

    Spring 依赖注入

    这种模式通过将对象间的依赖关系从对象内部转移到外部管理器(如Spring框架中的IOC容器)来实现。 **依赖注入的基本概念:** - **依赖(Dependency)**:在面向对象编程中,一个类通常需要依赖其他类的功能才能完成...

    Spring依赖注入原理解析.doc

    在传统编程中,对象通常自行创建和管理它们所依赖的其他对象,而在Spring中,这一过程被反转:Spring容器负责创建和管理对象,并将这些依赖对象注入到需要它们的地方。 依赖注入的主要思想是,一个对象(调用者)...

    spring 源码中文注释

    总的来说,"spring 源码中文注释"是一个宝贵的资源,它将带领我们走进Spring的内部世界,揭示那些在日常开发中看似透明的机制。通过学习源码,我们可以更全面地掌握Spring框架,提升自己的技术水平,更好地应对各种...

    spring项目启动加载类到静态服务类中的三种方式.zip

    但是,由于静态方法无法直接使用注解,我们可以创建一个非静态的辅助类,该类可以被Spring管理,并在其内部使用`@Autowired`注解来注入bean。之后,静态服务类通过这个辅助类访问bean。 ```java @Component ...

    spring 控制反转和依赖注入.docx

    Spring 控制反转和依赖注入基础知识详解 Spring 框架是 Java 企业级开发的轻量级开发框架,于 2003 年创建,主要用于解决企业级开发的复杂性。其主要优势在于分层架构,允许在不同层级中使用一个组件(其他框架)...

    Spring中的参数注入.pdf

    Spring框架是Java领域中最流行的开源应用程序框架,它广泛应用于企业级应用开发中。在Spring框架中,依赖注入(Dependency Injection, DI)是核心功能之一,允许开发者通过配置而非硬编码的方式将对象相互关联起来。...

    Spring依赖注入

    在探讨Spring框架中的依赖注入之前,我们首先需要了解两个核心概念:IoC(Inversion of Control)与DI(Dependency Injection)。这两个概念是理解Spring框架如何管理对象及其依赖关系的关键。 - **IoC (Inversion ...

    spring源码中英文注释

    这个压缩包文件中的"spring源码 中英文注释"为开发者提供了一个深入理解Spring框架内部工作原理的机会。通过阅读源码和注释,我们可以更清晰地了解Spring如何管理依赖注入、AOP(面向切面编程)、事务管理、上下文...

Global site tag (gtag.js) - Google Analytics