18.6.15springboot中關(guān)于Bean的注解
本節(jié)介紹注解:
@Component
@Service
@Scope
@Repository
@Controller
@RestController
@RequestMapping
@PathVariable
@ResponseBody
如何吸引Spring容器的注意而“有幸”成為Spring 容器管理的Bean呢狡相?
在Spring Boot中就依靠注解梯皿。Spring提供了多個(gè)注解來(lái)聲明Bean為Spring容器管理的Bean风钻,注解不同代表的含義不同进泼,但是對(duì)Spring容器來(lái)說(shuō)都是Spring管理的Bean母谎。
Spring IoC(ApplicationContext)容器負(fù)責(zé)進(jìn)行掃描Bean亡电,進(jìn)行Bean的初始化某筐、配置和依賴(lài)管理雹嗦。
聲明Bean的注解有:
@Component 沒(méi)有明確角色的組件
@Service 在業(yè)務(wù)邏輯層(Service層)使用
@Repositpry 在數(shù)據(jù)訪(fǎng)問(wèn)層(dao層)使用
@Controller 用于標(biāo)注控制層組件
@RestController
1、@Component注解
/**
- @since 2.5
- @see Repository
- @see Service
- @see Controller
- @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner // 掃描包中Bean仔拟,注冊(cè)
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
// 如果有返回組件名稱(chēng),否則返回空字符串
String value() default "";
}
@Component注解作用域默認(rèn)為singleton
@Component使用在不確定哪一個(gè)層的時(shí)候使用飒赃,可以作用在任何層次利花,把普通pojo實(shí)例化到spring容器
不推薦使用@Component注解,而應(yīng)該使用它的擴(kuò)展载佳,如@Service炒事、@Repository
2、@Service注解 - @see Component
- @see Repository
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Service是@Component注解的一個(gè)特例蔫慧,作用在類(lèi)上
@Service注解作用域默認(rèn)為singleton
使用注解配置和類(lèi)路徑掃描時(shí)挠乳,被@Service注解標(biāo)注的類(lèi)會(huì)被Spring掃描并注冊(cè)為Bean
@Service用于標(biāo)注業(yè)務(wù)層組件,表示定義一個(gè)bean
@Service使用時(shí)沒(méi)有傳參數(shù),Bean名稱(chēng)默認(rèn)為當(dāng)前類(lèi)的類(lèi)名,首字母小寫(xiě)
@Service(“serviceBeanId”)或@Service(value=”serviceBeanId”)使用時(shí)傳參數(shù)睡扬,使用value作為Bean名字
3盟蚣、@Scope注解
@Scope有5種取值:
基本作用域:
org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_SINGLETON = "singleton"
Spring 容器中有且只有一個(gè)Bean實(shí)例,只要Spring容器不銷(xiāo)毀或退出卖怜,該Bean實(shí)例就會(huì)一直存活
org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE = "prototype"
每次獲取Bean的時(shí)候會(huì)有一個(gè)新的實(shí)例屎开,Spring容器不能對(duì)返回Bean實(shí)例的整個(gè)生命周期負(fù)責(zé)
Web作用域:
org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST = "request"
request只適用于Web程序,每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的bean马靠,同時(shí)該bean僅在當(dāng)前HTTP request內(nèi)有效奄抽,當(dāng)請(qǐng)求結(jié)束后,該對(duì)象的生命周期即告結(jié)束
org.springframework.web.context.WebApplicationContext#SCOPE_SESSION = "session"
session只適用于Web程序甩鳄,session作用域表示該針對(duì)每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的bean逞度,同時(shí)該bean僅在當(dāng)前HTTP session內(nèi)有效
org.springframework.web.context.WebApplicationContext#SCOPE_APPLICATION = "application"
application只適用于Web程序,全局作用域
@Scope作用在類(lèi)上和方法上
@Scope用來(lái)配置 spring bean 的作用域妙啃,它標(biāo)識(shí) bean 的作用域
例如:
// 單例
@Service
@Scope("singleton")
public class SingletonScope {
public SingletonScope() {
}
}
//原型
@Service
@Scope("prototype")
public class PrototypeScope {
public PrototypeScope() {
}
}
4档泽、@Repository注解
- @see Component
- @see Service
- @see org.springframework.dao.DataAccessException
- @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Repository注解默認(rèn)作用域?yàn)閟inglton,單例
@Repository與@Scope注解一起使用可以修改Bean的作用域
5彬祖、@Controller注解 - @see Component
- @see org.springframework.web.bind.annotation.RequestMapping
- @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Controller注解作用在類(lèi)上
使用注解配置和類(lèi)路徑掃描時(shí)茁瘦,被@Controller注解標(biāo)注的類(lèi)會(huì)被Spring掃描并注冊(cè)為Bean
@Controller用于標(biāo)注Web中控制層組件
被@Controller標(biāo)注的類(lèi)負(fù)責(zé)處理由DispatcherServlet分發(fā)的請(qǐng)求,它把用戶(hù)請(qǐng)求的數(shù)據(jù)經(jīng)過(guò)業(yè)務(wù)處理層處理之后封裝成一個(gè)Model 储笑,然后再把該Model返回給對(duì)應(yīng)的View進(jìn)行展示
@Controller和@RequestMapping甜熔、@RequestParam等一些注解共同處理URL的映射
6、@RequestMapping注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
@RequestMapping注解作用在類(lèi)或方法上
@RequestMapping注解用來(lái)處理請(qǐng)求地址映射
@RequestMapping注解有7個(gè)屬性
value和path參數(shù)method參數(shù) consumes參數(shù)produces參數(shù)params參數(shù)headers參數(shù)
@RequestMapping請(qǐng)求路徑匹配
符號(hào) * 匹配任一字符
符號(hào) ** 匹配任意路徑
符號(hào) 突倍? 匹配單個(gè)字符
如果一個(gè)請(qǐng)求有多個(gè)@Requestmapping能夠匹配腔稀,通過(guò)匹配更具體的方法處理此請(qǐng)求
@RequestMapping注解標(biāo)注的方法可以接受多種類(lèi)型的參數(shù):
詳細(xì)參考書(shū)籍:Spring Boot精髓 從構(gòu)建小系統(tǒng)到架構(gòu)分布式大系統(tǒng)
@PathVariable - 將URL中的值映射到方法參數(shù)中
Model - Spring MVC中通用的模型
ModelAndView - 包含了模型和視圖路徑的對(duì)象
JavaBean - 將HTTP參數(shù)映射到JavaBean對(duì)象
MultipartFile - 用于處理文件上傳
@ModelAttribute - 用于將該注解的變量作為Model的一個(gè)屬性
7、@ResponseBody注解
@ResponseBody注解支持將返回值放在response體內(nèi)羽历,而不是返回一個(gè)視圖
@ResponseBody注解直接將返回的對(duì)象輸出到客戶(hù)端
如果返回字符串焊虏,直接返回
如果返回不是字符串,默認(rèn)使用Jackson將對(duì)象序列化成JSON字符串后輸出
8秕磷、@RestController注解/這個(gè)挺酷的诵闭。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
@AliasFor(annotation = Controller.class)
String value() default "";
}
@RestController是一個(gè)組合注解
@RestController = @Controller + @ResponseBody
@RestController注解直接將返回的對(duì)象輸出到客戶(hù)端
如果返回字符串,直接返回
如果返回不是字符串澎嚣,默認(rèn)使用Jackson將對(duì)象序列化成JSON字符串后輸出
參考:https://blog.csdn.net/lipinganq/article/details/79155072
——————————————————————
18.6.14
springboot自帶tomcat疏尿,因此無(wú)需配置自己的tomcat,如果想使用自己的tomcat易桃,需要增加<scope>provided</scope>標(biāo)簽褥琐,含義是告訴springboot我已經(jīng)提供了。
如果沒(méi)有提供tomcat晤郑,想要使用springboot自帶的tomcat敌呈,需要把provided注釋贸宏。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
——————————————————————
17.12.22
idea新建springboot項(xiàng)目有一個(gè)默認(rèn)目錄,頁(yè)面文件不在放在傳統(tǒng)的webapp頁(yè)面中磕洪。
資源文件夾下static文件夾用來(lái)存放web程序的靜態(tài)資源吭练,例如圖片、css褐鸥、js等线脚。
template文件夾存放web程序的視圖模板,html等需要渲染的模板文件就放在這里叫榕。
application.properties文件很重要浑侥,它是Spring Boot項(xiàng)目的全局配置文件。
Spring Boot項(xiàng)目更喜歡Java配置方式晰绎。因此從這里開(kāi)始寓落,所有的Spring配置都是用Java方式配置。
——————————————————————
17.12初
最近在研究springboot荞下。有一本Spring Boot實(shí)戰(zhàn) ,丁雪豐 (譯者) .pdf伶选。主要部分看了一遍。
學(xué)習(xí)了一下“自動(dòng)配置”和“啟動(dòng)依賴(lài)”尖昏。
具體的以后講仰税。
然后在網(wǎng)上找了idea搭建springboot的基礎(chǔ)教程,搭建自己的springboot抽诉。
教程很多陨簇,但是很多照著做自己實(shí)現(xiàn)的時(shí)候就是不行,現(xiàn)實(shí)就是這么有意思迹淌。
然后通過(guò)報(bào)錯(cuò)或者log滿(mǎn)滿(mǎn)排查研究河绽。遇到的問(wèn)題都寫(xiě)在這里。
1唉窃、所有教程都有一個(gè)helloword耙饰,以下是我的。
@RestController
public class HelloController {
@RequestMapping("/hello")
public String say(){
return "Hello beauty!";
}
}
然后run或debug后跑起來(lái)直接關(guān)閉了纹份,并沒(méi)有在后臺(tái)運(yùn)行苟跪。
解決:pom文件中tomcat依賴(lài),把<scope>provided</scope>蔓涧。注釋了就可以跑起來(lái)測(cè)試了削咆。
- provided,類(lèi)似compile蠢笋,期望JDK、容器或使用者會(huì)提供這個(gè)依賴(lài)鳞陨。如servlet.jar昨寞。
解析:provided的意思是只在編譯和測(cè)試階段可用這個(gè)包瞻惋。但是在實(shí)際發(fā)布階段則忽略這個(gè)包。
使用provided的原因是在編譯和測(cè)試的時(shí)候使用tomcat提供的包援岩,但是將war部署的服務(wù)器上的web服務(wù)器容器中歼狼,就會(huì)發(fā)生內(nèi)嵌的tomcat包和web服務(wù)器提供的包沖突。所以在編譯打包成war部署之前要添加provided享怀,這樣就能防止包的沖突羽峰。
而如果是自己本地啟動(dòng),并且沒(méi)有配置額外的tomcat添瓷,使用內(nèi)嵌的tomcat啟動(dòng)梅屉,則需要將provided注釋。
——————————————————