一個(gè)@Component注解引發(fā)的大坑
一個(gè)@Component注解引發(fā)的大坑
首先,我們這個(gè)是用springboot架構(gòu)來(lái)實(shí)現(xiàn)的業(yè)務(wù)
這是項(xiàng)目包結(jié)構(gòu)和配置文件結(jié)構(gòu)
這是定時(shí)需要執(zhí)行的任務(wù)
這是我執(zhí)行PromoCodeCMCJob這個(gè)定時(shí)器的報(bào)錯(cuò)信息
問題是這樣的
加了兩個(gè)MQ之后才報(bào)錯(cuò)的這個(gè)信息,當(dāng)我執(zhí)行啟動(dòng)PromoCodeCMCJob定時(shí)任務(wù)的時(shí)候就報(bào)錯(cuò),報(bào)錯(cuò)信息如上,這個(gè)時(shí)候我兩個(gè)MQ任務(wù)的定時(shí)任務(wù)都加了@Component和 @Autowired private MQProduceFactory gpRepayProducer 注入,此時(shí)就報(bào)錯(cuò)了,
剛開始的時(shí)候我只是 @Autowired private MQProduceFactory gpRepayProducer 注釋掉然后再啟動(dòng)PromoCodeCMCJob這個(gè)定時(shí)任務(wù),什么,居然沒問題,這個(gè)時(shí)候完全能執(zhí)啟動(dòng),所以此時(shí)我就斷定是這個(gè)MQProduceFactory注入原因引起的,但是我有MQ隊(duì)列,這個(gè)是MQ的生產(chǎn)者,
注釋掉就不能忘MQ生產(chǎn)消息了,所以注釋掉這個(gè)是不行的,然后我就想其它辦法去解決,像重新分包,想了各種解決辦法都沒有解決,始終沒有想到去掉@Component這個(gè)注解,這個(gè)注解翻譯是組件的意思,
是把當(dāng)前類注入到IOC容器中,直到我研究了半天左右的時(shí)候,一直沒有想到點(diǎn)上,浪費(fèi)了很多時(shí)間,快下班了的時(shí)候讓我想到了,既然被在IOC容器中了,那我不把他注入進(jìn)去不就完了,這是我就試著把@Component注解去掉,然后在配置文件中加入bean,變成了這樣
配置文件中不加這個(gè)bean的話啟動(dòng)定時(shí)任務(wù)也是會(huì)報(bào)錯(cuò)的,這樣的話我就把需要的MQProduceFactory這個(gè)放入到bean里面了,而沒有在IOC了,最后就完美的解決了,有MQ三個(gè)定時(shí)任務(wù)都能運(yùn)行了!
思考
@Component注解是IOC容器層面的,是個(gè)很大的容器,能包容很多,而bean只是一個(gè)工廠,IOC容器能包含著bean工廠,IOC容器中可以有很多bean工廠,
但是bean里面只有一個(gè),一般都是通過bean標(biāo)簽的id來(lái)標(biāo)識(shí)的,所以在項(xiàng)目中沒有最完美的方案,只有更好的方案,只有把架構(gòu),方案都用對(duì)了,才能更好去解決業(yè)務(wù)需求的問題。
對(duì)spring @component注解的理解
- 1、@controller 控制器(注入服務(wù))
- 2、@service 服務(wù)(注入dao)
- 3、@repository dao(實(shí)現(xiàn)dao訪問)
- 4、@component (把普通pojo實(shí)例化到spring容器中,相當(dāng)于配置文件中的<bean id="" class=""/>)
Spring 2.5 中除了提供 @Component 注釋外,還定義了幾個(gè)擁有特殊語(yǔ)義的注釋,它們分別是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,這 3 個(gè)注釋和 @Component 是等效的,但是從注釋類的命名上,很容易看出這 3 個(gè)注釋分別和持久層、業(yè)務(wù)層和控制層(Web 層)相對(duì)應(yīng)。雖然目前這 3 個(gè)注釋和 @Component 相比沒有什么新意,但 Spring 將在以后的版本中為它們添加特殊的功能。所以,如果 Web 應(yīng)用程序采用了經(jīng)典的三層分層結(jié)構(gòu)的話,最好在持久層、業(yè)務(wù)層和控制層分別采用 @Repository、@Service 和 @Controller 對(duì)分層中的類進(jìn)行注釋,而用 @Component 對(duì)那些比較中立的類進(jìn)行注釋。
在 一個(gè)稍大的項(xiàng)目中,通常會(huì)有上百個(gè)組件,如果這些組件采用xml的bean定義來(lái)配置,顯然會(huì)增加配置文件的體積,查找以及維護(hù)起來(lái)也不太方便。 Spring2.5為我們引入了組件自動(dòng)掃描機(jī)制,他可以在類路徑底下尋找標(biāo)注了 @Component,@Service,@Controller,@Repository注解的類,并把這些類納入進(jìn)spring容器中管理。它的作用 和在xml文件中使用bean節(jié)點(diǎn)配置組件時(shí)一樣的。
今天在做項(xiàng)目時(shí)把一個(gè)既不是業(yè)務(wù)控制(Controller)、又不是業(yè)務(wù)邏輯(Service)、也不是數(shù)據(jù)訪問(Dao)的類在不理解用注解@component的情況下注解成為Controller使用,結(jié)果肯定是有問題了,所以請(qǐng)教以后發(fā)現(xiàn)只用@component注解就完全可以解決了,所以在網(wǎng)上查閱了@component注解,特此記錄一下,方便日后查閱。
1、@controller 控制器(注入服務(wù))
- 用于標(biāo)注控制層,相當(dāng)于struts中的action層
2、@service 服務(wù)(注入dao)
- 用于標(biāo)注服務(wù)層,主要用來(lái)進(jìn)行業(yè)務(wù)的邏輯處理
3、@repository(實(shí)現(xiàn)dao訪問)
- 用于標(biāo)注數(shù)據(jù)訪問層,也可以說(shuō)用于標(biāo)注數(shù)據(jù)訪問組件,即DAO組件.
4、@component (把普通pojo實(shí)例化到spring容器中,相當(dāng)于配置文件中的 <bean id="" class=""/>)
- 泛指各種組件,就是說(shuō)當(dāng)我們的類不屬于各種歸類的時(shí)候(不屬于@Controller、@Services等的時(shí)候),我們就可以使用@Component來(lái)標(biāo)注這個(gè)類。
說(shuō)明:
<context:component-scan base-package=”com.*”>
上面的這個(gè)例子是引入Component組件的例子,其中base-package表示為需要掃描的所有子包。
共同點(diǎn):被@controller 、@service、@repository 、@component 注解的類,都會(huì)把這些類納入進(jìn)spring容器中進(jìn)行管理
@Component注解的使用
@Component取代 或者 @Component(“id”) 取代配置文件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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 組件掃描,掃描含有注解的類 --> <context:component-scan base-package="com.fly.spring.annotation"></context:component-scan> </beans>
注解的類
package com.fly.spring.annotation; import org.springframework.stereotype.Component; @Component("person") public class Person { public void getString(){ System.out.println("*********hello everyOne**********"); } }
測(cè)試的類
package com.fly.spring.annotation; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestDemo { @Test public void demo(){ String xmlpath = "com/fly/spring/annotation/applicationContext.xml"; ApplicationContext context = new ClassPathXmlApplicationContext(xmlpath); Person bean = (Person) context.getBean("person"); bean.getString(); } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java多線程中的ReentrantLock可中斷鎖詳細(xì)解讀
這篇文章主要介紹了Java多線程中的ReentrantLock可中斷鎖詳細(xì)解讀,ReentrantLock中的lockInterruptibly()方法使得線程可以在被阻塞時(shí)響應(yīng)中斷,比如一個(gè)線程t1通過lockInterruptibly()方法獲取到一個(gè)可重入鎖,并執(zhí)行一個(gè)長(zhǎng)時(shí)間的任務(wù),需要的朋友可以參考下2023-12-12java實(shí)現(xiàn)微信小程序登錄態(tài)維護(hù)的示例代碼
本篇文章主要介紹了java實(shí)現(xiàn)微信小程序登錄態(tài)維護(hù)的示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下2017-09-09java使用jacob.jar將word轉(zhuǎn)pdf
這篇文章主要為大家詳細(xì)介紹了java利用jacob.jar將word轉(zhuǎn)pdf,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12Java?數(shù)據(jù)庫(kù)連接池Druid?的介紹
這篇文章主要給大家分享的是?Java?數(shù)據(jù)庫(kù)連接池Druid?的介紹,Druid是一個(gè)JDBC組件,它包括三部分:?DruidDriver?代理Driver,能夠提供基于Filter-Chain模式的插件體系。?DruidDataSource?高效可管理的數(shù)據(jù)庫(kù)連接池,下面來(lái)看看文中的詳細(xì)內(nèi)容,需要的朋友也可以參考一下2021-11-11SpringBoot?Loki安裝簡(jiǎn)介及實(shí)戰(zhàn)思路
這篇文章主要為大家介紹了SpringBoot?Loki安裝簡(jiǎn)介及實(shí)戰(zhàn)思路詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪的相關(guān)資料2022-11-11JavaSE實(shí)戰(zhàn)之酒店訂房系統(tǒng)的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了如何利用JavaSE實(shí)現(xiàn)酒店訂房系統(tǒng),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)JavaSE開發(fā)有一定的幫助,需要的可以參考一下2022-07-07Mybatis-Plus查詢中如何排除標(biāo)識(shí)字段
這篇文章主要介紹了Mybatis-Plus查詢中排除標(biāo)識(shí)字段的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06SpringCloud微服務(wù)續(xù)約實(shí)現(xiàn)源碼分析詳解
這篇文章主要介紹了SpringCloud微服務(wù)續(xù)約實(shí)現(xiàn)源碼分析,服務(wù)續(xù)期和服務(wù)注冊(cè)非常相似,服務(wù)注冊(cè)在Eureka?Client程序啟動(dòng)之后開啟,并同時(shí)開啟服務(wù)續(xù)期的定時(shí)任務(wù)2022-11-11