IDEA搭建Spring boot問題集

搭建好的Spring boot運行時出現以下問題:

問題一:

***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified and no embedded datasource could be auto-configured.

Reason: Failed to determine a suitable driver class


Action:

Consider the following:
    If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
    If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).


Process finished with exit code 1

解決方案:

搭建數據庫,添加數據庫配置信息

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test
spring.datasource.username=root
spring.datasource.password=654321
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

所使用的數據庫爲mysql

 

問題二:service注入失敗

***************************
APPLICATION FAILED TO START
***************************

Description:

Field testInterFace in com.testInterface.TestBootController required a bean of type 'com.testInterface.TestInterface' that could not be found.
Action:

Consider defining a bean of type 'com.testInterface.TestInterface' in your configuration.

根據英文的提示是在配置中找不到一個指定自動注入類型的bean,經過多方排查得出結論: 相信大家對這種異常非常常見,注入失敗,這時候問題來了,按照傳統的方式,對注入進行檢查。service層已經加了@service的註解,怎麼還是注入失敗了呢,想查看配置文件,發現springboot沒有配置文件,那麼他是怎麼掃描註解的呢?正常情況下加上@Component註解的類會自動被Spring掃描到生成Bean註冊到spring容器中,既然他說沒找到,也就是該註解被沒有被spring識別,問題的核心關鍵就在application類的註解SpringBootApplication上 

這個註解其實相當於下面這一堆註解的效果,其中一個註解就是@Component,在默認情況下只能掃描與控制器在同一個包下以及其子包下的@Component註解,以及能將指定註解的類自動註冊爲Bean的@Service@Controller和@ Repository

springboot默認按照包順序注入,所以在創建controller時service還沒有注入,springboot不需要傳統的xml配置掃描包,只需要添加註解@ComponentScan(basePackages={“com.testInterface”})

注意:紅色部分爲需要注入的包

 

問題三:@Autowired注入失敗

問題描述:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field userDao in com.lar.testInterface.service.impl.TestInterfaceImpl required a bean of type 'com.lar.testInterface.dao.UserDao' that could not be found.


Action:

Consider defining a bean of type 'com.lar.testInterface.dao.UserDao' in your configuration.

 

失敗注入代碼:

解決方案:

controller 是作爲控制器被spring 調用的,如果你非要用也得使用@Autowired注入,這樣才能得到被spring管理的bean,就沒問題了

(一)

SpringBoot項目的Bean裝配默認規則是根據Application類所在的包位置從上往下掃描!
“Application類”是指SpringBoot項目入口類。這個類的位置很關鍵:
如果Application類所在的包爲:com.boot.app,則只會掃描com.boot.app包及其所有子包,如果service或dao所在包不在com.boot.app及其子包下,則不會被掃描!
即, 把Application類放到dao、service所在包的上級,com.boot.Application

(二)

SpringBoot中Service自動注入很方便,例:

Service.class(接口類)

ServiceImpl.class(實現類)

Controller.class(使用類)

用以上三個類來說一下自動注入:

單項目:分別ServiceImpl頭上@Service,Controller中Service對象@Autowired即可享用;

Multi modules 場景,三個(種)類分別在三個module下:

moduleA : Service.class(com.example.moduleA )

moduleB : ServiceImpl.class ( com.example.moduleB )

moduleC : Controller.class ( com.example.moduleC )

此時B依賴A,C依賴A、B,添加好依賴關係。

如何自動注入?

1、接口、實現、使用類,姿勢不變,按單項目方式寫即可;

2、在moduleC的Application中做手腳!

 

如果你已經試過scanBasePackages,無論是在@SpringBootApplication方式還是@ComponentScan;

抑或試過@SpringBootApplication、@ComponentScan同時用,當你這麼做時,一定是絕望的。

 

解決辦法@SpringBootApplictaion(scanBasePackages="com.example")

核心就是:

Service 及 ServiceImpl均需在com.example包下

 

因爲Service、ServiceImpl同在com.example下(C可以不在),所以我看作是同一次scan過程;

比如若是這樣寫scanBasePackages={" com.example.moduleA , com.example.moduleB "},則會失敗;

當然(@ComponentScan="com.example")也是可以的,因爲前者@SpringBootApplication已經包含@ComponentScan;

(三)

mapper(Dao層)

1 package com.demo.mapper;
 2 
 3 import org.apache.ibatis.annotations.Mapper;
 4 
 5 import com.demo.domain.User;
 6 
 7 @Mapper
 8 public interface UserMapper {
 9 
10     public User gYeMian(User u);
11 
12     public int sYeMian(User u);
13 
14 }

(四)

Application(啓動類)

1 package com.demo;
 2 
 3 import org.mybatis.spring.annotation.MapperScan;
 4 import org.springframework.boot.SpringApplication;
 5 import org.springframework.boot.autoconfigure.SpringBootApplication;
 6 
 7 @SpringBootApplication
 8 @MapperScan(value = "com.demo.mapper")
 9 public class App 
10 {
11     public static void main(String[] args) throws Exception {
12         SpringApplication.run(App.class, args);
13     }
14 }

原因:在mybatis-spring-boot-autoconfigure的jar包中有一個類 MybatisAutoConfiguration,在這個類中的registerBeanDefinitions方法告訴了我們

1 @Override
 2     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
 3 
 4       logger.debug("Searching for mappers annotated with @Mapper");
 5 
 6       ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
 7 
 8       try {
 9         if (this.resourceLoader != null) {
10           scanner.setResourceLoader(this.resourceLoader);
11         }
12 
13         List<String> packages = AutoConfigurationPackages.get(this.beanFactory);
14         if (logger.isDebugEnabled()) {
15           for (String pkg : packages) {
16             logger.debug("Using auto-configuration base package '{}'", pkg);
17           }
18         }
19 
20         scanner.setAnnotationClass(Mapper.class);
21         scanner.registerFilters();
22         scanner.doScan(StringUtils.toStringArray(packages));
23       } catch (IllegalStateException ex) {
24         logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled.", ex);
25       }
26     }

(五)

這是由於springBoot啓動時,沒有掃描到com.lar.testInterface.dao.UserDao ,而在com.lar.testInterface.TestInterface中又使用了@autowired private EnfileDao entFileDao進行裝配,所以會發現錯誤,說沒有定義。此時需要在springBoot的啓動類上,加個註解:@MapperScan("持久層路徑"),這樣就會掃描到com.lar.testInterface.dao.UserDao了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章