入口注解:
@SpringBootApplication
@SpringBootApplication酝陈,springboot項目啟動入口注解,是由@SpringBootConfiguration白粉、 @EnableAutoConfiguration背传、 @ComponentScan三個注解組合而成拯欧。
配置注解:
@SpringBootConfiguration
@SpringBootConfiguration是springboot對于spring注解@Configuration的派生注解,標(biāo)注這個類是一個配置類
@EnableAutoConfiguration
@EnableAutoConfiguration注解建芙,開啟自動裝配旷偿。是由@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class)組合而成。
包掃描注解:
@ComponentScan
@ComponentScan自動掃描組件包降允,只要標(biāo)注了@Controller恩闻、@Service、@Repository剧董、@Component這四個注解都會被掃描到容器中幢尚。
@Service:服務(wù)層組件,用于標(biāo)注業(yè)務(wù)層組件,表示定義一個bean翅楼,自動根據(jù)bean的類名實例化一個首寫字母為小寫的bean尉剩,例如Chinese實例化為chinese,如果需要自己改名字則:@Service("你自己改的bean名")毅臊。
@Controller:用于標(biāo)注控制層組件(如struts中的action) 理茎。
@Repository:持久層組件,用于標(biāo)注數(shù)據(jù)訪問組件,即DAO組件功蜓。
@Component泛指組件园爷,當(dāng)組件不好歸類的時候,我們可以使用這個注解進(jìn)行標(biāo)注式撼。
SpringBoot在寫啟動類的時候如果不使用@ComponentScan指明對象掃描范圍童社,默認(rèn)指掃描當(dāng)前啟動類所在的包里的對象,如果你的其他包都在使用了@SpringBootApplication注解的主類所在的包及其下級包著隆,則你什么都不用做扰楼,SpringBoot會自動幫你把其他包都掃描了。為了方便美浦,我們一般都把主類放在了所有類的上一級包中弦赖,如項目所有的class文件都放在了包com.beauty的下級包中,則把spring boot的主類放在包com.beauty下浦辨。
如果當(dāng)前啟動類沒有包蹬竖,則在啟動時會報錯:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package錯誤,因為啟動類不能直接放在main/java文件夾下流酬,必須要建一個包把它放進(jìn)去或者使用@ComponentScan指明要掃描的包币厕。
如果你有一些bean所在的包,不在主類的包及其下級包芽腾,那么你需要手動加上@ComponentScan注解并指定那個bean所在的包旦装。
注:@ComponentScan的不同寫法
1.@ComponentScan({“com.xiao.hui”,“com.xiao.qiang”})或@ComponentScan(basePackages = {“com.xiao.hui”,“com.xiao.qiang”})
2.@ComponentScan(“com.xiao”)或@ComponentScan(value = “com.xiao”)或@ComponentScan(basePackages = { “com.xiao” })
3.@ComponentScan(basePackageClasses=要掃描類.class所在位置的包) 意思是要掃描哪個類所在的包,如@ComponentScan(basePackageClasses=hehe.class)摊滔,這種寫法不如上面的那種寫法好有局限性
@ServletComponentScan
在SpringBootApplication上使用@ServletComponentScan注解后阴绢,Servlet、Filter艰躺、Listener可以直接通過@WebServlet呻袭、@WebFilter、@WebListener注解自動注冊描滔,無需其他代碼棒妨。
IOC:
在接口前面標(biāo)上@Autowired和@Qualifier注釋使得接口可以被容器注入,當(dāng)接口存在兩個實現(xiàn)類的時候必須指定其中一個來注入含长,使用實現(xiàn)類首字母小寫的字符串來注入券腔,如:
@Autowired
@Qualifier("chinese")
private Man man;
否則可以省略,只寫@Autowired 拘泞。
Spring不但支持自己定義的@Autowired注解纷纫,還支持幾個由JSR-250規(guī)范定義的注解,它們分別是@Resource陪腌、@PostConstruct以及@PreDestroy辱魁。
@Resource的作用相當(dāng)于@Autowired烟瞧,只不過@Autowired按byType自動注入,而@Resource默認(rèn)按 byName自動注入罷了染簇。@Resource有兩個屬性是比較重要的参滴,分是name和type,Spring將@Resource注解的name屬性解析為bean的名字锻弓,而type屬性則解析為bean的類型砾赔。所以如果使用name屬性,則使用byName的自動注入策略青灼,而使用type屬性時則使用byType自動注入策略暴心。如果既不指定name也不指定type屬性,這時將通過反射機(jī)制使用byName自動注入策略杂拨。
@Resource裝配順序
- 如果同時指定了name和type专普,則從Spring上下文中找到唯一匹配的bean進(jìn)行裝配,找不到則拋出異常
- 如果指定了name弹沽,則從上下文中查找名稱(id)匹配的bean進(jìn)行裝配檀夹,找不到則拋出異常
- 如果指定了type,則從上下文中找到類型匹配的唯一bean進(jìn)行裝配策橘,找不到或者找到多個击胜,都會拋出異常
- 如果既沒有指定name,又沒有指定type役纹,則自動按照byName方式進(jìn)行裝配;如果沒有匹配暇唾,則回退為一個原始類型進(jìn)行匹配促脉,如果匹配則自動裝配;
@Autowired 與@Resource的區(qū)別:
1策州、 @Autowired與@Resource都可以用來裝配bean.都可以寫在字段上,或?qū)懺趕etter方法上瘸味。
2、 @Autowired默認(rèn)按類型裝配(這個注解是屬業(yè)spring的)够挂,默認(rèn)情況下必須要求依賴對象必須存在旁仿,如果要允許null值,可以設(shè)置它的required屬性為false孽糖,如:@Autowired(required=false)枯冈,如果我們想使用名稱裝配可以結(jié)合@Qualifier注解進(jìn)行使用,如下:
@Autowired() @Qualifier("baseDao")
private BaseDao baseDao;
3办悟、@Resource(這個注解屬于J2EE的)尘奏,默認(rèn)安裝名稱進(jìn)行裝配,名稱可以通過name屬性進(jìn)行指定病蛉,如果沒有指定name屬性炫加,當(dāng)注解寫在字段上時瑰煎,默認(rèn)取字段名進(jìn)行安裝名稱查找,如果注解寫在setter方法上默認(rèn)取屬性名進(jìn)行裝配俗孝。當(dāng)找不到與名稱匹配的bean時才按照類型進(jìn)行裝配酒甸。但是需要注意的是,如果name屬性一旦指定赋铝,就只會按照名稱進(jìn)行裝配插勤。
@Resource(name="baseDao")
private BaseDao baseDao;
推薦使用:@Resource注解在字段上,這樣就不用寫setter方法了柬甥,并且這個注解是屬于J2EE的饮六,減少了與spring的耦合。這樣代碼看起就比較優(yōu)雅苛蒲。
AOP:
基本概念
切面(Advisor):表示從業(yè)務(wù)邏輯中分離出來的橫切邏輯卤橄,比如性能監(jiān)控,日志記錄臂外,權(quán)限控制等
連接點(JointPoint):程序執(zhí)行過程中明確的點窟扑,一般是方法的調(diào)用
通知(Advice): 通知是切面的一種實現(xiàn),可以完成簡單的織入功能漏健。通知定義了增強(qiáng)代碼切入到目標(biāo)代碼的時間點嚎货,是目標(biāo)方法執(zhí)行之前執(zhí)行,還是執(zhí)行之后執(zhí)行等蔫浆。切入點定義切入的位置殖属,通知定義切入的時間
切入點(PointCut): 就是帶有通知的連接點,切入點指切面具體織入的方法
織入(Weaving): 織入是指將切面代碼插入到目標(biāo)對象的過程。代理的invoke方法完成的工作瓦盛,可以稱為織入
目標(biāo)對象(Target): 目標(biāo)對象指將要被增強(qiáng)的對象洗显。即包含主業(yè)務(wù)邏輯的類的對象
實現(xiàn)方式:
spring對AOP有兩種實現(xiàn)方式,一種是動態(tài)代理原环,它是通過接口方式實現(xiàn)的挠唆,要求所代理的類一定是實現(xiàn)了某一個接口,對一般的類就無法代理嘱吗,spring默認(rèn)是這種玄组;一種是通過設(shè)置proxy-target-class="true",則是使用CGLIB實現(xiàn)AOP谒麦,CGLIB直接生成二進(jìn)制碼俄讹,使得普通類也可以實現(xiàn)AOP。
1.添加aop依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.配置參數(shù):
spring.aop.proxy-target-class="true"
注解:
- @Aspect: 將一個java類定義為切面類
- @Pointcut: 定義一個切入點绕德,可以是一個規(guī)則表達(dá)式
- @Order(i): 當(dāng)有多個切面滿足條件時颅悉,需要定義切面的優(yōu)先級,i值越小越先執(zhí)行
- @Before: 在切入點開始處切入內(nèi)容
- @After: 在切入點結(jié)尾處切入內(nèi)容
- @AfterReturning: 在切入點return內(nèi)容之后切入內(nèi)容(可以用來對處理返回值做一些加工處理)
- @Around: 在切入點前后切入內(nèi)容迁匠,并自己控制何時執(zhí)行切入點自身的內(nèi)容
- @AfterThrowing: 用來處理當(dāng)切入內(nèi)容部分拋出異常之后的處理邏輯
當(dāng)同時有個多切面需要執(zhí)行時剩瓶,通過Order來定義優(yōu)先級驹溃,值越小越優(yōu)先執(zhí)行。例如有兩個切面延曙,一個是記錄請求@Order(1)豌鹤,一個是驗證接口中的參數(shù)@Order(2),那么切面方法的執(zhí)行順序是先執(zhí)行@Order(1)的before, 再執(zhí)行@Order(2)的before; 然后再執(zhí)行@Order(2)的@After或@AfterReturning枝缔,最后再執(zhí)行@Order(1)的@After或@AfterReturning