2016-03-02 4 views
0

У меня есть простая программа загрузки Spring Boot Java, и она использует @Autowired.Spring @ComponentScan ("com.junk") позволяет автоувеличиванию работать?

Если я не добавлю в аннотацию @ComponentScan, я получаю: org.springframework.beans.factory.NoSuchBeanDefinitionException сбои во время выполнения.

Weirdly любой@ComponentScan исправляет проводку, даже если это относится к несуществующей упаковке.

Должно ли @ComponentScan требовать действительный пакет в качестве аргумента?

package com.example.demo; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.annotation.ComponentScan; 

@SpringBootApplication 
// @ComponentScan // This one causes auto-wired problems. See below. 
@ComponentScan("com.junk.foo") // This one works? 

public class DemoApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(DemoApplication.class, args); 
    } 
} 

EDIT в ответ на вопросы в комментариях ...

По autowire проблем, я имею в виду с @ComponentScan или без этой аннотации я получаю ...

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.foo.Foo] 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)} 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373) 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119) 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) 
     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545) 
     ... 25 more 

а если я использую @ComponentScan("com.junk.foo") У меня нет проблем с автопроводом.

Ошибка:

:: Spring Boot ::  (v1.3.2.RELEASE) 


// SNIP FOR BREVITY 

Exception in thread "main" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException 
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:62) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:54) 
    ... 1 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'barService': Injection of autowired dependencies failed; nested exception is 

// SNIP FOR BREVITY 

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.foo.Foo] 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)} 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545) 
    ... 25 more 

Мой проект, как это ...

├── pom.xml 
└── src 
    └── main 
     ├── java 
     │   └── com 
     │    ├── bar 
     │    │   └── BarService.java 
     │    ├── example 
     │    │   └── demo 
     │    │    └── DemoApplication.java 
     │    └── foo 
     │     └── Foo.java 
     └── resources 
+0

Можете ли вы опубликовать класс, в который вы помещаете @Autowired annotation и свою структуру проекта? –

+0

Что вы подразумеваете под «работами»? @ComponentScan - синтаксическая ошибка. Вам нужно указать имя пакета или имя класса. Название класса является лучшим выбором, потому что оно действительно существует. Ваш com.junk.foo будет удовлетворять требованиям синтаксиса Annotation, но это не поможет получить вещи Autowired. – Terry

+0

Фактически '@ ComponentScan' является допустимой аннотацией, а не синтаксической ошибкой. '@ ComponentScan' берет пакет аннотированного класса в качестве пакета по умолчанию для сканирования, который в этом, например, это 'com.example.demo'. Также вам не нужно добавлять '@ ComponentScan', если вы не даете массив пакетов, потому что' @ SpringBootApplication' уже имеет это внутри. –

ответ

0

С ошибками вы вывешенные я могу видеть, у вас есть проблемы Autowire как в случае.

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.foo.Foo] 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)} есть в обоих случаях.

Теперь, чтобы ответить вам вопрос:

@ComponentScan принимает пакет аннотированного класса в пакете по умолчанию для сканирования, которые в этом, например, есть com.example.demo. Так весна только сканирование com.example.demo и будет сканировать любой суб-пакет т.е. com.example.demo.blah

Если вы хотите простое решение, где вы не хотите, чтобы попасть в боль управления ComponentScan самостоятельно рассмотреть структурирование кода, как предложено в spring docs.

Если вы хотите продолжить с текущей структурой попробовать это на основной метод DemoApplication.java:

@ComponentScan({"com.bar", "com.example.demo", "com.foo"})

Аналогично, в будущем, если у вас есть еще один пакет сказать com.one.more.pack, то вы бы добавить, что в ComponentScan как это @ComponentScan({"com.bar", "com.example.demo", "com.foo", "com.one.more.pack"})

Смежные вопросы