1.@Configuration注解
該類等價(jià)與XML中配置的beans,相當(dāng)于IOC容器,它的某個(gè)方法的頭上如果用了@Bean,則它會(huì)作為Spring容器中的bean,與XML配置的bean功能相同
@Configuration注解的類必須使用<context:component-scanbase-package="XXX"/>掃描。如下:
@Configuration
public class ScheduleConfig {
//讀取配置文件的值
@Value("${vschedule.port}")
private Integer port;
@Bean
public JobNode jobNodeConfig() {
JobNode node = new JobNode();
node.setDoJobServicePort(port);
node.setAppName("feedback-service");
return node;
}
}
定義一個(gè)ScheduleConfig ,用@Configuration注解,那ScheduleConfig 相當(dāng)于xml里的beans,里面用@Bean注解的和xml里定義的bean等價(jià),用<context:component-scanbase-package=”XXX”/>掃描該類所在的包,最終我們可以在程序里用@AutoWired或@Resource注解取得用@Bean注解的bean,和用xml先配置bean然后在程序里自動(dòng)注入一樣。目的是減少xml里配置
2.@Value注解
為了簡(jiǎn)化配置文件里取值,可以使用此注解@Value獲取配置文件里的值,在spring項(xiàng)目中可以在XML文件中引入文件:
<context:property-placeholder location="classpath*:props/schedule.properties" ignore-unresolvable="true"/>
讀取方法為:
//讀取配置文件的值
@Value("${vschedule.port}")
private Integer port;
即使給變量賦了初值也會(huì)以配置文件的值為準(zhǔn)。
3. 用在類上的注解@Controller, @Service, @Repository, @Component
在Spring2.0之前的版本中,@Repository注解可以標(biāo)記在任何的類上,用來(lái)表明該類是用來(lái)執(zhí)行與數(shù)據(jù)庫(kù)相關(guān)的操作(即dao對(duì)象),并支持自動(dòng)處理數(shù)據(jù)庫(kù)操作產(chǎn)生的異常
在Spring2.5版本中,引入了更多的Spring類注解:@Component,@Service,@Controller。@Component是一個(gè)通用的Spring容器管理的單例bean組件。而@Repository, @Service, @Controller就是針對(duì)不同的使用場(chǎng)景所采取的特定功能化的注解組件。
因此,當(dāng)你的一個(gè)類被@Component所注解,那么就意味著同樣可以用@Repository, @Service, @Controller來(lái)替代它,同時(shí)這些注解會(huì)具備有更多的功能,而且功能各異。
最后,如果你不知道要在項(xiàng)目的業(yè)務(wù)層采用@Service還是@Component注解。那么,@Service是一個(gè)更好的選擇。
@Controller對(duì)應(yīng)表現(xiàn)層上的Bean,也就是Action,例如:
@Controller
public class TeacherCommentController {
......
}
@Service對(duì)應(yīng)業(yè)務(wù)層Bean,例如:
@Service
@Scope("prototype")
public class RecommendCourseServiceImpl implements RecommendCourseService {
.....
}
@Scope
注:@Scope("prototype")表示將Action的范圍聲明為原型,可以利用容器的scope="prototype"來(lái)保證每一個(gè)請(qǐng)求有一個(gè)單獨(dú)的Action來(lái)處理,避免struts中Action的線程安全問(wèn)題。spring 默認(rèn)scope 是單例模式(scope="singleton"),這樣只會(huì)創(chuàng)建一個(gè)Action對(duì)象,每次訪問(wèn)都是同一Action對(duì)象,數(shù)據(jù)不安全,struts2 是要求每次次訪問(wèn)都對(duì)應(yīng)不同的Action,scope="prototype" 可以保證當(dāng)有請(qǐng)求的時(shí)候都創(chuàng)建一個(gè)Action對(duì)象
@Repository一般針對(duì)數(shù)據(jù)處理層即dao層,例如:
@Repository
public interface TeacherCommentDao{
public List<TeacherComment> findByTeacherIdAndTimeRange(Map condition);
.......
}
其他網(wǎng)上資料
這幾個(gè)注解幾乎可以說(shuō)是一樣的:因?yàn)楸贿@些注解修飾的類就會(huì)被Spring掃描到并注入到Spring的bean容器中。
這里,有兩個(gè)注解是不能被其他注解所互換的:
@Controller
注解的bean會(huì)被spring-mvc框架所使用。
@Repository
會(huì)被作為持久層操作(數(shù)據(jù)庫(kù))的bean來(lái)使用
如果想使用自定義的組件注解,那么只要在你定義的新注解中加上@Component即可:
@Component
@Scope("prototype")
public @interface ScheduleJob {...}
這樣,所有被@ScheduleJob
注解的類就都可以注入到spring容器來(lái)進(jìn)行管理。我們所需要做的,就是寫一些新的代碼來(lái)處理這個(gè)自定義注解(譯者注:可以用反射的方法),進(jìn)而執(zhí)行我們想要執(zhí)行的工作。
@Component
就是跟<bean>
一樣,可以托管到Spring容器進(jìn)行管理。
@Service
, @Controller
, @Repository
= {@Component
+ 一些特定的功能}。這個(gè)就意味著這些注解在部分功能上是一樣的。
當(dāng)然,下面三個(gè)注解被用于為我們的應(yīng)用進(jìn)行分層:
@Controller
注解類進(jìn)行前端請(qǐng)求的處理,轉(zhuǎn)發(fā),重定向。包括調(diào)用Service層的方法
@Service
注解類處理業(yè)務(wù)邏輯
@Repository
注解類作為DAO對(duì)象(數(shù)據(jù)訪問(wèn)對(duì)象,Data Access Objects),這些類可以直接對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作
有這些分層操作的話,代碼之間就實(shí)現(xiàn)了松耦合,代碼之間的調(diào)用也清晰明朗,便于項(xiàng)目的管理;假想一下,如果只用@Controller
注解,那么所有的請(qǐng)求轉(zhuǎn)發(fā),業(yè)務(wù)處理,數(shù)據(jù)庫(kù)操作代碼都糅合在一個(gè)地方,那這樣的代碼該有多難拓展和維護(hù)。
總結(jié)
@Component
, @Service
, @Controller
, @Repository
是spring注解,注解后可以被spring框架所掃描并注入到spring容器來(lái)進(jìn)行管理
@Component
是通用注解,其他三個(gè)注解是這個(gè)注解的拓展,并且具有了特定的功能
@Repository
注解在持久層中,具有將數(shù)據(jù)庫(kù)操作拋出的原生異常翻譯轉(zhuǎn)化為spring的持久層異常的功能。
@Controller
層是spring-mvc的注解,具有將請(qǐng)求進(jìn)行轉(zhuǎn)發(fā),重定向的功能。
@Service
層是業(yè)務(wù)邏輯層注解,這個(gè)注解只是標(biāo)注該類處于業(yè)務(wù)邏輯層。
用這些注解對(duì)應(yīng)用進(jìn)行分層之后,就能將請(qǐng)求處理,義務(wù)邏輯處理,數(shù)據(jù)庫(kù)操作處理分離出來(lái),為代碼解耦,也方便了以后項(xiàng)目的維護(hù)和開(kāi)發(fā)。
注解 | 含義 |
---|---|
@Component | 最普通的組件,可以被注入到spring容器進(jìn)行管理 |
@Repository | 作用于持久層 |
@Service | 作用于業(yè)務(wù)邏輯層 |
@Controller | 作用于表現(xiàn)層(spring-mvc的注解) |
4. @PostConstruct 和 @PreDestory
實(shí)現(xiàn)初始化和銷毀bean之前進(jìn)行的操作,只能有一個(gè)方法可以用此注釋進(jìn)行注釋,方法不能有參數(shù),返回值必需是void,方法需要是非靜態(tài)的。
@PostConstruct:在構(gòu)造方法和init方法(如果有的話)之間得到調(diào)用,且只會(huì)執(zhí)行一次。
@PreDestory:注解的方法在destory()方法調(diào)用后得到執(zhí)行。
5. @Primary
自動(dòng)裝配時(shí)當(dāng)出現(xiàn)多個(gè)Bean候選者時(shí),被注解為@Primary的Bean將作為首選者,否則將拋出異常。
6. @Lazy(true)
用于指定該Bean是否取消預(yù)初始化,用于注解類,延遲初始化。
6. @Autowired 和 @Resource
1、@Autowired與@Resource都可以用來(lái)裝配bean. 都可以寫在字段上,或?qū)懺趕etter方法上。
2、@Autowired默認(rèn)按類型裝配(這個(gè)注解是屬于spring的),默認(rèn)情況下必須要求依賴對(duì)象必須存在,如果要允許null值,可以設(shè)置它的required屬性為false,如:
@Autowired(required=false) ,如果我們想使用名稱裝配可以結(jié)合@Qualifier注解進(jìn)行使用,如下:
Java代碼
@Autowired() @Qualifier("baseDao")
private BaseDao baseDao;
3、@Resource 是JDK1.6支持的注解,默認(rèn)按照名稱進(jìn)行裝配,名稱可以通過(guò)name屬性進(jìn)行指定,如果沒(méi)有指定name屬性,當(dāng)注解寫在字段上時(shí),默認(rèn)取字段名,按照名稱查找,如果注解寫在setter方法上默認(rèn)取屬性名進(jìn)行裝配。當(dāng)找不到與名稱匹配的bean時(shí)才按照類型進(jìn)行裝配。但是需要注意的是,如果name屬性一旦指定,就只會(huì)按照名稱進(jìn)行裝配。
兩者的區(qū)別:
@Resource默認(rèn)按照名稱方式進(jìn)行bean匹配,@Autowired默認(rèn)按照類型方式進(jìn)行bean匹配
@Resource(import javax.annotation.Resource;)是J2EE的注解,@Autowired( import org.springframework.beans.factory.annotation.Autowired;)是Spring的注解