Spring或者Spring启动中没有类型的 Bean
在本教程中,我们将看到一个例外:没有类型的 Bean类。
springframework.beans.factory.nosuchbeandefinitionException:没有限定 Bean类?
让我们看看有哪些原因
理由1:你忘了声明 Bean。
让我们在举例的帮助下了解这一点。
XML配置
1.创建一个简单的Java Maven项目。
2.
Maven依赖性将Spring和Cglib Maven依赖于Pom.xml。
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- cglib required for @configuration annotation --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.0</version> </dependency> </dependencies> <properties> <spring.version>4.2.1.RELEASE</spring.version> </properties>
所以你的pom.xml看起来像:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"< <modelVersion<4.0.0</modelVersion> <groupId>org.igi.theitroad</groupId> <artifactId>SpringHelloWorldJavaBasedConfiguration</artifactId> <version>0.0.1-SNAPSHOT</version> <name>SpringHelloWorldJavaBasedConfiguration</name> <description>It provides hello world program for java based config </description> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- cglib required for @configuration annotation --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.0</version> </dependency> </dependencies> <properties> <spring.version>4.2.1.RELEASE</spring.version> </properties> </project>
3.创建bean类
在package org.igi.theitroad中创建一个名为x.java的bean类。
package org.igi.theitroad; import org.springframework.beans.factory.annotation.Autowired; public class X { @Autowired Y y; public Y getY() { return y; } public void setY(Y y) { this.y = y; } }
请注意,我们使用自动注释注释在x中注入bean y。
在package org.igi.theitroad中创建一个名为y.java的 Bean类类。
package org.igi.theitroad; public class Y { public void methodY() { System.out.println("In method Y"); } }
- ApplicationContext.xml在SRC/Main/Resources中创建ApplicationContext.xml,如下所示。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="x" class="org.igi.theitroad.X"> </bean> <context:annotation-config </beans>
我们刚刚在此介绍了一个bean x 5.创建SpringApplicationMain.java
package org.igi.theitroad; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * * Spring Application main */ public class SpringApplicationMain { public static void main( String[] args ) { ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("ApplicationContext.xml"); X firstX = (X) ac.getBean("x"); Y firstY = firstX.getY(); ac.close(); } }
6.在运行上面的程序时运行它,我们将得到以下输出。
. . Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.igi.theitroad.Y] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} . .
正如我们所看到的,我们获得了nosuchbeandefinitionException:没有XML中没有声明的bean"y"的类型的合格 Bean。
Java配置
前2个步骤保持不变。
让我们将@Component添加到X.
java.
package org.igi.theitroad; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class X { @Autowired Y y; public Y getY() { return y; } public void setY(Y y) { this.y = y; } }
在package org.igi.theitroad中创建一个名为y.java的 Bean类类。
package org.igi.theitroad; public class Y { public void methodY() { System.out.println("In method Y"); } }
4.创建ApplicationConfiguration.java,如下所示。
package org.igi.theitroad; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("org.igi.theitroad") public class ApplicationConfiguration { }
5.创建主类
package org.igi.theitroad; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;; public class SpringJavaConfigMain { public static void main(String[] args) { @SuppressWarnings("resource") ApplicationContext appContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class); X x = (X) appContext.getBean("x"); Y y = x.getY(); } }
6.运行它时运行它,我们将得到以下输出。
. . Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.igi.theitroad.Y] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} . .
如果将@Component添加到Y.java,则不会发生高于异常。
原因2:我们还没有将包名称添加到@ComponentsCan。
我们可能是在使用@组件,@ service或者@repository,但是与@componentscan的包没有条目。
例如:如果将包名称更改为"org.igi.dummy",则程序将无法正常工作,即使我们已将@component与bean y汇总。
package org.igi.theitroad; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("org.igi.dummy") public class ApplicationConfiguration { }
原因3:我们有多个候选人用于自动定向
让我们在举例的帮助下了解这一点。
让我们说你一个名为"装饰"的接口
package org.igi.theitroad; public interface Decorable { public void decorate(); }
此接口由两个类实现。
curtiandecorator.java.java.
package org.igi.theitroad; import org.springframework.stereotype.Component; @Component public class CurtianDecorator implements Decorable { @Override public void decorate() { System.out.println("Decorating room using curtains"); } }
walldecorator.java.
package org.igi.theitroad; import org.springframework.stereotype.Component; @Component public class WallDecorator implements Decorable { @Override public void decorate() { System.out.println("Decorating room with wall decorators"); } }
创建房间.java,它将复合类型接口的参考变量装饰。
package org.igi.theitroad; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Room { @Autowired Decorable decorable; public Decorable getDecorable() { return decorable; } public void setDecorable(Decorable decorable) { this.decorable = decorable; } }
4.创建ApplicationConfiguration.java,如下所示。
package org.igi.theitroad; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("org.igi.theitroad") public class ApplicationConfiguration { }
5.创建主类
package org.igi.theitroad; package org.igi.theitroad; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;; public class SpringJavaConfigMain { public static void main(String[] args) { @SuppressWarnings("resource") ApplicationContext appContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class); Room room=(Room)appContext.getBean("room"); Decorable decorable = room.getDecorable(); decorable.decorate(); } }
6.运行它时运行它,我们将得到以下输出。
. . . Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.igi.theitroad.Decorable] is defined: expected single matching bean but found 2: curtianDecorator,wallDecorator . .
请注意,这一次,我们获得了NouniqueBeanDefinitionException,因为有两种自动候选人在室内类中装饰,Spring无法解决哪一个使用。
我们可以使用@qualifier注释来解决此问题。
package org.igi.theitroad; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component public class Room { @Autowired @Qualifier("wallDecorator") Decorable decorable; public Decorable getDecorable() { return decorable; } public void setDecorable(Decorable decorable) { this.decorable = decorable; } }
当我们再次运行该程序时,我们将得到以下输出:
Jun 24, 2016 5:19:36 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2e817b38: startup date [Sun Jun 24 17:19:36 IST 2016]; root of context hierarchy Decorating room with wall decorators