一個(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ò)信息

問(wèn)題是這樣的
加了兩個(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ò)了,
剛開(kāi)始的時(shí)候我只是 @Autowired private MQProduceFactory gpRepayProducer 注釋掉然后再啟動(dòng)PromoCodeCMCJob這個(gè)定時(shí)任務(wù),什么,居然沒(méi)問(wèn)題,這個(gè)時(shí)候完全能執(zhí)啟動(dòng),所以此時(shí)我就斷定是這個(gè)MQProduceFactory注入原因引起的,但是我有MQ隊(duì)列,這個(gè)是MQ的生產(chǎn)者,
注釋掉就不能忘MQ生產(chǎn)消息了,所以注釋掉這個(gè)是不行的,然后我就想其它辦法去解決,像重新分包,想了各種解決辦法都沒(méi)有解決,始終沒(méi)有想到去掉@Component這個(gè)注解,這個(gè)注解翻譯是組件的意思,
是把當(dāng)前類(lèi)注入到IOC容器中,直到我研究了半天左右的時(shí)候,一直沒(méi)有想到點(diǎn)上,浪費(fèi)了很多時(shí)間,快下班了的時(shí)候讓我想到了,既然被在IOC容器中了,那我不把他注入進(jìn)去不就完了,這是我就試著把@Component注解去掉,然后在配置文件中加入bean,變成了這樣

配置文件中不加這個(gè)bean的話啟動(dòng)定時(shí)任務(wù)也是會(huì)報(bào)錯(cuò)的,這樣的話我就把需要的MQProduceFactory這個(gè)放入到bean里面了,而沒(méi)有在IOC了,最后就完美的解決了,有MQ三個(gè)定時(shí)任務(wù)都能運(yùn)行了!
思考
@Component注解是IOC容器層面的,是個(gè)很大的容器,能包容很多,而bean只是一個(gè)工廠,IOC容器能包含著bean工廠,IOC容器中可以有很多bean工廠,
但是bean里面只有一個(gè),一般都是通過(guò)bean標(biāo)簽的id來(lái)標(biāo)識(shí)的,所以在項(xiàng)目中沒(méi)有最完美的方案,只有更好的方案,只有把架構(gòu),方案都用對(duì)了,才能更好去解決業(yè)務(wù)需求的問(wèn)題。
對(duì)spring @component注解的理解
- 1、@controller 控制器(注入服務(wù))
- 2、@service 服務(wù)(注入dao)
- 3、@repository dao(實(shí)現(xiàn)dao訪問(wèn))
- 4、@component (把普通pojo實(shí)例化到spring容器中,相當(dāng)于配置文件中的<bean id="" class=""/>)
Spring 2.5 中除了提供 @Component 注釋外,還定義了幾個(gè)擁有特殊語(yǔ)義的注釋?zhuān)鼈兎謩e是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,這 3 個(gè)注釋和 @Component 是等效的,但是從注釋類(lèi)的命名上,很容易看出這 3 個(gè)注釋分別和持久層、業(yè)務(wù)層和控制層(Web 層)相對(duì)應(yīng)。雖然目前這 3 個(gè)注釋和 @Component 相比沒(méi)有什么新意,但 Spring 將在以后的版本中為它們添加特殊的功能。所以,如果 Web 應(yīng)用程序采用了經(jīng)典的三層分層結(jié)構(gòu)的話,最好在持久層、業(yè)務(wù)層和控制層分別采用 @Repository、@Service 和 @Controller 對(duì)分層中的類(lèi)進(jìn)行注釋?zhuān)?@Component 對(duì)那些比較中立的類(lèi)進(jìn)行注釋。
在 一個(gè)稍大的項(xiàng)目中,通常會(huì)有上百個(gè)組件,如果這些組件采用xml的bean定義來(lái)配置,顯然會(huì)增加配置文件的體積,查找以及維護(hù)起來(lái)也不太方便。 Spring2.5為我們引入了組件自動(dòng)掃描機(jī)制,他可以在類(lèi)路徑底下尋找標(biāo)注了 @Component,@Service,@Controller,@Repository注解的類(lèi),并把這些類(lèi)納入進(jìn)spring容器中管理。它的作用 和在xml文件中使用bean節(jié)點(diǎn)配置組件時(shí)一樣的。
今天在做項(xiàng)目時(shí)把一個(gè)既不是業(yè)務(wù)控制(Controller)、又不是業(yè)務(wù)邏輯(Service)、也不是數(shù)據(jù)訪問(wèn)(Dao)的類(lèi)在不理解用注解@component的情況下注解成為Controller使用,結(jié)果肯定是有問(wèn)題了,所以請(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訪問(wèn))
- 用于標(biāo)注數(shù)據(jù)訪問(wèn)層,也可以說(shuō)用于標(biāo)注數(shù)據(jù)訪問(wèn)組件,即DAO組件.
4、@component (把普通pojo實(shí)例化到spring容器中,相當(dāng)于配置文件中的 <bean id="" class=""/>)
- 泛指各種組件,就是說(shuō)當(dāng)我們的類(lèi)不屬于各種歸類(lèi)的時(shí)候(不屬于@Controller、@Services等的時(shí)候),我們就可以使用@Component來(lái)標(biāo)注這個(gè)類(lèi)。
說(shuō)明:
<context:component-scan base-package=”com.*”>
上面的這個(gè)例子是引入Component組件的例子,其中base-package表示為需要掃描的所有子包。
共同點(diǎn):被@controller 、@service、@repository 、@component 注解的類(lèi),都會(huì)把這些類(lèi)納入進(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">
<!-- 組件掃描,掃描含有注解的類(lèi) -->
<context:component-scan base-package="com.fly.spring.annotation"></context:component-scan>
</beans>
注解的類(lèi)
package com.fly.spring.annotation;
import org.springframework.stereotype.Component;
@Component("person")
public class Person {
public void getString(){
System.out.println("*********hello everyOne**********");
}
}
測(cè)試的類(lèi)
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中獲取當(dāng)前年份(實(shí)例代碼)
在Java語(yǔ)言中獲取當(dāng)前年份有幾種方法:使用java.util包下的Calendar類(lèi),使用java.time包下的LocalDate類(lèi)或者使用java.text包下的SimpleDateFormat類(lèi),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2023-11-11
Java String字符串補(bǔ)0或空格的實(shí)現(xiàn)代碼
這篇文章主要介紹了Java String字符串補(bǔ)0或空格的實(shí)現(xiàn)代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-09-09
spring-data-jpa中findOne與getOne的區(qū)別說(shuō)明
這篇文章主要介紹了spring-data-jpa中findOne與getOne的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
SpringBoot2整合ElasticJob框架過(guò)程詳解
這篇文章主要介紹了SpringBoot2整合ElasticJob框架過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
SpringBoot解決數(shù)據(jù)庫(kù)時(shí)間和返回時(shí)間格式不一致的問(wèn)題
這篇文章主要介紹了SpringBoot解決數(shù)據(jù)庫(kù)時(shí)間和返回時(shí)間格式不一致的問(wèn)題,文章通過(guò)代碼示例和圖文結(jié)合的方式講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)和工作有一定的幫助,需要的朋友可以參考下2024-03-03
java面向?qū)ο笤O(shè)計(jì)原則之里氏替換原則示例詳解
這篇文章主要為大家介紹了java面向?qū)ο笤O(shè)計(jì)原則之里氏替換原則示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2021-10-10
struts2+spring+ibatis框架整合實(shí)現(xiàn)增刪改查
這篇文章主要為大家詳細(xì)介紹了struts2+spring+ibatis框架整合實(shí)現(xiàn)增刪改查操作,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07

